aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-29 19:53:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-29 19:53:48 -0400
commit12679a2d7e3bfbdc7586e3e86d1ca90c46659363 (patch)
treed9c00f2e599d1c3e04a349229a6a19906d01f99e /arch/arm
parent1c036588772d01655d851f75dffc27c971e072e2 (diff)
parentb0df89868006517417251e02cc4ce5d4b0165885 (diff)
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
Pull more ARM updates from Russell King. This got a fair number of conflicts with the <asm/system.h> split, but also with some other sparse-irq and header file include cleanups. They all looked pretty trivial, though. * 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (59 commits) ARM: fix Kconfig warning for HAVE_BPF_JIT ARM: 7361/1: provide XIP_VIRT_ADDR for no-MMU builds ARM: 7349/1: integrator: convert to sparse irqs ARM: 7259/3: net: JIT compiler for packet filters ARM: 7334/1: add jump label support ARM: 7333/2: jump label: detect %c support for ARM ARM: 7338/1: add support for early console output via semihosting ARM: use set_current_blocked() and block_sigmask() ARM: exec: remove redundant set_fs(USER_DS) ARM: 7332/1: extract out code patch function from kprobes ARM: 7331/1: extract out insn generation code from ftrace ARM: 7330/1: ftrace: use canonical Thumb-2 wide instruction format ARM: 7351/1: ftrace: remove useless memory checks ARM: 7316/1: kexec: EOI active and mask all interrupts in kexec crash path ARM: Versatile Express: add NO_IOPORT ARM: get rid of asm/irq.h in asm/prom.h ARM: 7319/1: Print debug info for SIGBUS in user faults ARM: 7318/1: gic: refactor irq_start assignment ARM: 7317/1: irq: avoid NULL check in for_each_irq_desc loop ARM: 7315/1: perf: add support for the Cortex-A7 PMU ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig23
-rw-r--r--arch/arm/Kconfig.debug16
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/.gitignore2
-rw-r--r--arch/arm/boot/compressed/Makefile15
-rw-r--r--arch/arm/boot/compressed/decompress.c6
-rw-r--r--arch/arm/boot/compressed/piggy.xzkern.S6
-rw-r--r--arch/arm/common/gic.c13
-rw-r--r--arch/arm/configs/integrator_defconfig8
-rw-r--r--arch/arm/include/asm/elf.h4
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h6
-rw-r--r--arch/arm/include/asm/hardware/it8152.h3
-rw-r--r--arch/arm/include/asm/irq.h8
-rw-r--r--arch/arm/include/asm/jump_label.h41
-rw-r--r--arch/arm/include/asm/mc146818rtc.h4
-rw-r--r--arch/arm/include/asm/memory.h2
-rw-r--r--arch/arm/include/asm/mmu_context.h29
-rw-r--r--arch/arm/include/asm/opcodes.h59
-rw-r--r--arch/arm/include/asm/page.h2
-rw-r--r--arch/arm/include/asm/perf_event.h1
-rw-r--r--arch/arm/include/asm/processor.h1
-rw-r--r--arch/arm/include/asm/prom.h2
-rw-r--r--arch/arm/include/asm/tlbflush.h136
-rw-r--r--arch/arm/include/asm/traps.h2
-rw-r--r--arch/arm/kernel/Makefile14
-rw-r--r--arch/arm/kernel/debug.S25
-rw-r--r--arch/arm/kernel/ftrace.c100
-rw-r--r--arch/arm/kernel/head.S8
-rw-r--r--arch/arm/kernel/insn.c61
-rw-r--r--arch/arm/kernel/insn.h29
-rw-r--r--arch/arm/kernel/irq.c5
-rw-r--r--arch/arm/kernel/jump_label.c39
-rw-r--r--arch/arm/kernel/kprobes.c86
-rw-r--r--arch/arm/kernel/machine_kexec.c25
-rw-r--r--arch/arm/kernel/patch.c75
-rw-r--r--arch/arm/kernel/patch.h7
-rw-r--r--arch/arm/kernel/perf_event.c3
-rw-r--r--arch/arm/kernel/perf_event_v7.c145
-rw-r--r--arch/arm/kernel/process.c36
-rw-r--r--arch/arm/kernel/sched_clock.c18
-rw-r--r--arch/arm/kernel/setup.c1
-rw-r--r--arch/arm/kernel/signal.c24
-rw-r--r--arch/arm/kernel/smp.c17
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c19
-rw-r--r--arch/arm/mach-davinci/time.c28
-rw-r--r--arch/arm/mach-highbank/highbank.c1
-rw-r--r--arch/arm/mach-highbank/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-integrator/core.c3
-rw-r--r--arch/arm/mach-integrator/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c10
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c3
-rw-r--r--arch/arm/mach-integrator/pci.c3
-rw-r--r--arch/arm/mach-integrator/pci_v3.c3
-rw-r--r--arch/arm/mach-mmp/aspenite.c5
-rw-r--r--arch/arm/mach-mmp/avengers_lite.c1
-rw-r--r--arch/arm/mach-mmp/brownstone.c4
-rw-r--r--arch/arm/mach-mmp/flint.c3
-rw-r--r--arch/arm/mach-mmp/gplugd.c2
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-mmp/irq-mmp2.c1
-rw-r--r--arch/arm/mach-mmp/jasper.c5
-rw-r--r--arch/arm/mach-mmp/tavorevb.c1
-rw-r--r--arch/arm/mach-mmp/teton_bga.c3
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c4
-rw-r--r--arch/arm/mach-msm/timer.c12
-rw-r--r--arch/arm/mach-picoxcell/include/mach/irqs.h20
-rw-r--r--arch/arm/mach-prima2/timer.c21
-rw-r--r--arch/arm/mach-pxa/capc7117.c1
-rw-r--r--arch/arm/mach-pxa/cm-x300.c1
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c2
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c1
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c1
-rw-r--r--arch/arm/mach-pxa/corgi.c3
-rw-r--r--arch/arm/mach-pxa/csb726.c1
-rw-r--r--arch/arm/mach-pxa/devices.c1
-rw-r--r--arch/arm/mach-pxa/em-x270.c2
-rw-r--r--arch/arm/mach-pxa/gumstix.c1
-rw-r--r--arch/arm/mach-pxa/h5000.c1
-rw-r--r--arch/arm/mach-pxa/himalaya.c1
-rw-r--r--arch/arm/mach-pxa/icontrol.c1
-rw-r--r--arch/arm/mach-pxa/idp.c1
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/mainstone.h2
-rw-r--r--arch/arm/mach-pxa/mioa701.c1
-rw-r--r--arch/arm/mach-pxa/mp900.c1
-rw-r--r--arch/arm/mach-pxa/palmld.c1
-rw-r--r--arch/arm/mach-pxa/palmt5.c1
-rw-r--r--arch/arm/mach-pxa/palmtc.c1
-rw-r--r--arch/arm/mach-pxa/palmte2.c1
-rw-r--r--arch/arm/mach-pxa/palmtreo.c2
-rw-r--r--arch/arm/mach-pxa/palmtx.c1
-rw-r--r--arch/arm/mach-pxa/palmz72.c1
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c1
-rw-r--r--arch/arm/mach-pxa/raumfeld.c3
-rw-r--r--arch/arm/mach-pxa/saar.c1
-rw-r--r--arch/arm/mach-pxa/spitz.c3
-rw-r--r--arch/arm/mach-pxa/stargate2.c1
-rw-r--r--arch/arm/mach-pxa/tavorevb.c1
-rw-r--r--arch/arm/mach-pxa/time.c1
-rw-r--r--arch/arm/mach-pxa/trizeps4.c2
-rw-r--r--arch/arm/mach-pxa/viper.c1
-rw-r--r--arch/arm/mach-pxa/vpac270.c1
-rw-r--r--arch/arm/mach-pxa/xcep.c1
-rw-r--r--arch/arm/mach-pxa/z2.c1
-rw-r--r--arch/arm/mach-shmobile/Kconfig4
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-bonito.c1
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-kota2.c1
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c1
-rw-r--r--arch/arm/mach-shmobile/board-marzen.c1
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-shmobile/intc-r8a7740.c1
-rw-r--r--arch/arm/mach-shmobile/intc-sh7367.c1
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c1
-rw-r--r--arch/arm/mach-shmobile/intc-sh7377.c1
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c1
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c1
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c1
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c1
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c1
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c1
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c1
-rw-r--r--arch/arm/mach-vexpress/include/mach/io.h1
-rw-r--r--arch/arm/mm/cache-l2x0.c22
-rw-r--r--arch/arm/mm/copypage-v4mc.c9
-rw-r--r--arch/arm/mm/copypage-v6.c20
-rw-r--r--arch/arm/mm/copypage-xscale.c9
-rw-r--r--arch/arm/mm/dma-mapping.c20
-rw-r--r--arch/arm/mm/fault.c3
-rw-r--r--arch/arm/mm/flush.c14
-rw-r--r--arch/arm/mm/highmem.c21
-rw-r--r--arch/arm/mm/init.c4
-rw-r--r--arch/arm/mm/mm.h26
-rw-r--r--arch/arm/mm/mmu.c7
-rw-r--r--arch/arm/mm/vmregion.c76
-rw-r--r--arch/arm/mm/vmregion.h5
-rw-r--r--arch/arm/net/Makefile3
-rw-r--r--arch/arm/net/bpf_jit_32.c915
-rw-r--r--arch/arm/net/bpf_jit_32.h190
-rw-r--r--arch/arm/plat-nomadik/Kconfig1
-rw-r--r--arch/arm/plat-versatile/Kconfig3
144 files changed, 2192 insertions, 510 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5098564d587..242f3a33d74 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -9,6 +9,7 @@ config ARM
9 select SYS_SUPPORTS_APM_EMULATION 9 select SYS_SUPPORTS_APM_EMULATION
10 select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) 10 select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
11 select HAVE_OPROFILE if (HAVE_PERF_EVENTS) 11 select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
12 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
12 select HAVE_ARCH_KGDB 13 select HAVE_ARCH_KGDB
13 select HAVE_KPROBES if !XIP_KERNEL 14 select HAVE_KPROBES if !XIP_KERNEL
14 select HAVE_KRETPROBES if (HAVE_KPROBES) 15 select HAVE_KRETPROBES if (HAVE_KPROBES)
@@ -21,6 +22,7 @@ config ARM
21 select HAVE_KERNEL_GZIP 22 select HAVE_KERNEL_GZIP
22 select HAVE_KERNEL_LZO 23 select HAVE_KERNEL_LZO
23 select HAVE_KERNEL_LZMA 24 select HAVE_KERNEL_LZMA
25 select HAVE_KERNEL_XZ
24 select HAVE_IRQ_WORK 26 select HAVE_IRQ_WORK
25 select HAVE_PERF_EVENTS 27 select HAVE_PERF_EVENTS
26 select PERF_USE_VMALLOC 28 select PERF_USE_VMALLOC
@@ -28,10 +30,10 @@ config ARM
28 select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) 30 select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
29 select HAVE_C_RECORDMCOUNT 31 select HAVE_C_RECORDMCOUNT
30 select HAVE_GENERIC_HARDIRQS 32 select HAVE_GENERIC_HARDIRQS
31 select HAVE_SPARSE_IRQ
32 select GENERIC_IRQ_SHOW 33 select GENERIC_IRQ_SHOW
33 select CPU_PM if (SUSPEND || CPU_IDLE) 34 select CPU_PM if (SUSPEND || CPU_IDLE)
34 select GENERIC_PCI_IOMAP 35 select GENERIC_PCI_IOMAP
36 select HAVE_BPF_JIT if NET
35 help 37 help
36 The ARM series is a line of low-power-consumption RISC chip designs 38 The ARM series is a line of low-power-consumption RISC chip designs
37 licensed by ARM Ltd and targeted at embedded applications and 39 licensed by ARM Ltd and targeted at embedded applications and
@@ -52,9 +54,6 @@ config MIGHT_HAVE_PCI
52config SYS_SUPPORTS_APM_EMULATION 54config SYS_SUPPORTS_APM_EMULATION
53 bool 55 bool
54 56
55config HAVE_SCHED_CLOCK
56 bool
57
58config GENERIC_GPIO 57config GENERIC_GPIO
59 bool 58 bool
60 59
@@ -269,6 +268,7 @@ config ARCH_INTEGRATOR
269 select PLAT_VERSATILE 268 select PLAT_VERSATILE
270 select PLAT_VERSATILE_FPGA_IRQ 269 select PLAT_VERSATILE_FPGA_IRQ
271 select NEED_MACH_MEMORY_H 270 select NEED_MACH_MEMORY_H
271 select SPARSE_IRQ
272 help 272 help
273 Support for ARM's Integrator platform. 273 Support for ARM's Integrator platform.
274 274
@@ -315,6 +315,7 @@ config ARCH_VEXPRESS
315 select HAVE_CLK 315 select HAVE_CLK
316 select HAVE_PATA_PLATFORM 316 select HAVE_PATA_PLATFORM
317 select ICST 317 select ICST
318 select NO_IOPORT
318 select PLAT_VERSATILE 319 select PLAT_VERSATILE
319 select PLAT_VERSATILE_CLCD 320 select PLAT_VERSATILE_CLCD
320 help 321 help
@@ -354,6 +355,7 @@ config ARCH_HIGHBANK
354 select GENERIC_CLOCKEVENTS 355 select GENERIC_CLOCKEVENTS
355 select HAVE_ARM_SCU 356 select HAVE_ARM_SCU
356 select HAVE_SMP 357 select HAVE_SMP
358 select SPARSE_IRQ
357 select USE_OF 359 select USE_OF
358 help 360 help
359 Support for the Calxeda Highbank SoC based boards. 361 Support for the Calxeda Highbank SoC based boards.
@@ -442,7 +444,6 @@ config ARCH_MXC
442 select CLKDEV_LOOKUP 444 select CLKDEV_LOOKUP
443 select CLKSRC_MMIO 445 select CLKSRC_MMIO
444 select GENERIC_IRQ_CHIP 446 select GENERIC_IRQ_CHIP
445 select HAVE_SCHED_CLOCK
446 select MULTI_IRQ_HANDLER 447 select MULTI_IRQ_HANDLER
447 help 448 help
448 Support for Freescale MXC/iMX-based family of processors 449 Support for Freescale MXC/iMX-based family of processors
@@ -537,7 +538,6 @@ config ARCH_IXP4XX
537 select CPU_XSCALE 538 select CPU_XSCALE
538 select GENERIC_GPIO 539 select GENERIC_GPIO
539 select GENERIC_CLOCKEVENTS 540 select GENERIC_CLOCKEVENTS
540 select HAVE_SCHED_CLOCK
541 select MIGHT_HAVE_PCI 541 select MIGHT_HAVE_PCI
542 select DMABOUNCE if PCI 542 select DMABOUNCE if PCI
543 help 543 help
@@ -608,7 +608,6 @@ config ARCH_MMP
608 select CLKDEV_LOOKUP 608 select CLKDEV_LOOKUP
609 select GENERIC_CLOCKEVENTS 609 select GENERIC_CLOCKEVENTS
610 select GPIO_PXA 610 select GPIO_PXA
611 select HAVE_SCHED_CLOCK
612 select TICK_ONESHOT 611 select TICK_ONESHOT
613 select PLAT_PXA 612 select PLAT_PXA
614 select SPARSE_IRQ 613 select SPARSE_IRQ
@@ -649,7 +648,6 @@ config ARCH_TEGRA
649 select GENERIC_CLOCKEVENTS 648 select GENERIC_CLOCKEVENTS
650 select GENERIC_GPIO 649 select GENERIC_GPIO
651 select HAVE_CLK 650 select HAVE_CLK
652 select HAVE_SCHED_CLOCK
653 select HAVE_SMP 651 select HAVE_SMP
654 select MIGHT_HAVE_CACHE_L2X0 652 select MIGHT_HAVE_CACHE_L2X0
655 select ARCH_HAS_CPUFREQ 653 select ARCH_HAS_CPUFREQ
@@ -666,7 +664,6 @@ config ARCH_PICOXCELL
666 select DW_APB_TIMER 664 select DW_APB_TIMER
667 select GENERIC_CLOCKEVENTS 665 select GENERIC_CLOCKEVENTS
668 select GENERIC_GPIO 666 select GENERIC_GPIO
669 select HAVE_SCHED_CLOCK
670 select HAVE_TCM 667 select HAVE_TCM
671 select NO_IOPORT 668 select NO_IOPORT
672 select SPARSE_IRQ 669 select SPARSE_IRQ
@@ -694,7 +691,6 @@ config ARCH_PXA
694 select ARCH_REQUIRE_GPIOLIB 691 select ARCH_REQUIRE_GPIOLIB
695 select GENERIC_CLOCKEVENTS 692 select GENERIC_CLOCKEVENTS
696 select GPIO_PXA 693 select GPIO_PXA
697 select HAVE_SCHED_CLOCK
698 select TICK_ONESHOT 694 select TICK_ONESHOT
699 select PLAT_PXA 695 select PLAT_PXA
700 select SPARSE_IRQ 696 select SPARSE_IRQ
@@ -761,7 +757,6 @@ config ARCH_SA1100
761 select CPU_FREQ 757 select CPU_FREQ
762 select GENERIC_CLOCKEVENTS 758 select GENERIC_CLOCKEVENTS
763 select CLKDEV_LOOKUP 759 select CLKDEV_LOOKUP
764 select HAVE_SCHED_CLOCK
765 select TICK_ONESHOT 760 select TICK_ONESHOT
766 select ARCH_REQUIRE_GPIOLIB 761 select ARCH_REQUIRE_GPIOLIB
767 select HAVE_IDE 762 select HAVE_IDE
@@ -818,7 +813,6 @@ config ARCH_S5P64X0
818 select CLKSRC_MMIO 813 select CLKSRC_MMIO
819 select HAVE_S3C2410_WATCHDOG if WATCHDOG 814 select HAVE_S3C2410_WATCHDOG if WATCHDOG
820 select GENERIC_CLOCKEVENTS 815 select GENERIC_CLOCKEVENTS
821 select HAVE_SCHED_CLOCK
822 select HAVE_S3C2410_I2C if I2C 816 select HAVE_S3C2410_I2C if I2C
823 select HAVE_S3C_RTC if RTC_CLASS 817 select HAVE_S3C_RTC if RTC_CLASS
824 help 818 help
@@ -849,7 +843,6 @@ config ARCH_S5PV210
849 select CLKSRC_MMIO 843 select CLKSRC_MMIO
850 select ARCH_HAS_CPUFREQ 844 select ARCH_HAS_CPUFREQ
851 select GENERIC_CLOCKEVENTS 845 select GENERIC_CLOCKEVENTS
852 select HAVE_SCHED_CLOCK
853 select HAVE_S3C2410_I2C if I2C 846 select HAVE_S3C2410_I2C if I2C
854 select HAVE_S3C_RTC if RTC_CLASS 847 select HAVE_S3C_RTC if RTC_CLASS
855 select HAVE_S3C2410_WATCHDOG if WATCHDOG 848 select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -892,7 +885,6 @@ config ARCH_U300
892 depends on MMU 885 depends on MMU
893 select CLKSRC_MMIO 886 select CLKSRC_MMIO
894 select CPU_ARM926T 887 select CPU_ARM926T
895 select HAVE_SCHED_CLOCK
896 select HAVE_TCM 888 select HAVE_TCM
897 select ARM_AMBA 889 select ARM_AMBA
898 select ARM_PATCH_PHYS_VIRT 890 select ARM_PATCH_PHYS_VIRT
@@ -951,7 +943,6 @@ config ARCH_OMAP
951 select ARCH_HAS_CPUFREQ 943 select ARCH_HAS_CPUFREQ
952 select CLKSRC_MMIO 944 select CLKSRC_MMIO
953 select GENERIC_CLOCKEVENTS 945 select GENERIC_CLOCKEVENTS
954 select HAVE_SCHED_CLOCK
955 select ARCH_HAS_HOLES_MEMORYMODEL 946 select ARCH_HAS_HOLES_MEMORYMODEL
956 help 947 help
957 Support for TI's OMAP platform (OMAP1/2/3/4). 948 Support for TI's OMAP platform (OMAP1/2/3/4).
@@ -1115,13 +1106,11 @@ config ARCH_ACORN
1115config PLAT_IOP 1106config PLAT_IOP
1116 bool 1107 bool
1117 select GENERIC_CLOCKEVENTS 1108 select GENERIC_CLOCKEVENTS
1118 select HAVE_SCHED_CLOCK
1119 1109
1120config PLAT_ORION 1110config PLAT_ORION
1121 bool 1111 bool
1122 select CLKSRC_MMIO 1112 select CLKSRC_MMIO
1123 select GENERIC_IRQ_CHIP 1113 select GENERIC_IRQ_CHIP
1124 select HAVE_SCHED_CLOCK
1125 1114
1126config PLAT_PXA 1115config PLAT_PXA
1127 bool 1116 bool
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 66ca8014ff3..85348a09d65 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -292,6 +292,22 @@ choice
292 Note that the system will appear to hang during boot if there 292 Note that the system will appear to hang during boot if there
293 is nothing connected to read from the DCC. 293 is nothing connected to read from the DCC.
294 294
295 config DEBUG_SEMIHOSTING
296 bool "Kernel low-level debug output via semihosting I"
297 help
298 Semihosting enables code running on an ARM target to use
299 the I/O facilities on a host debugger/emulator through a
300 simple SVC calls. The host debugger or emulator must have
301 semihosting enabled for the special svc call to be trapped
302 otherwise the kernel will crash.
303
304 This is known to work with OpenOCD, as wellas
305 ARM's Fast Models, or any other controlling environment
306 that implements semihosting.
307
308 For more details about semihosting, please see
309 chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
310
295endchoice 311endchoice
296 312
297config EARLY_PRINTK 313config EARLY_PRINTK
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index dcb088e868f..047a20780fc 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -253,6 +253,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
253 253
254# If we have a machine-specific directory, then include it in the build. 254# If we have a machine-specific directory, then include it in the build.
255core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ 255core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
256core-y += arch/arm/net/
256core-y += $(machdirs) $(platdirs) 257core-y += $(machdirs) $(platdirs)
257 258
258drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ 259drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
index e0936a14851..d0d441c429a 100644
--- a/arch/arm/boot/compressed/.gitignore
+++ b/arch/arm/boot/compressed/.gitignore
@@ -1,8 +1,10 @@
1ashldi3.S
1font.c 2font.c
2lib1funcs.S 3lib1funcs.S
3piggy.gzip 4piggy.gzip
4piggy.lzo 5piggy.lzo
5piggy.lzma 6piggy.lzma
7piggy.xzkern
6vmlinux 8vmlinux
7vmlinux.lds 9vmlinux.lds
8 10
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index cf0a64ce4b8..bb267562e7e 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -92,6 +92,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
92suffix_$(CONFIG_KERNEL_GZIP) = gzip 92suffix_$(CONFIG_KERNEL_GZIP) = gzip
93suffix_$(CONFIG_KERNEL_LZO) = lzo 93suffix_$(CONFIG_KERNEL_LZO) = lzo
94suffix_$(CONFIG_KERNEL_LZMA) = lzma 94suffix_$(CONFIG_KERNEL_LZMA) = lzma
95suffix_$(CONFIG_KERNEL_XZ) = xzkern
95 96
96# Borrowed libfdt files for the ATAG compatibility mode 97# Borrowed libfdt files for the ATAG compatibility mode
97 98
@@ -112,10 +113,12 @@ endif
112 113
113targets := vmlinux vmlinux.lds \ 114targets := vmlinux vmlinux.lds \
114 piggy.$(suffix_y) piggy.$(suffix_y).o \ 115 piggy.$(suffix_y) piggy.$(suffix_y).o \
115 lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS) 116 lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \
117 font.o font.c head.o misc.o $(OBJS)
116 118
117# Make sure files are removed during clean 119# Make sure files are removed during clean
118extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs) 120extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \
121 lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs)
119 122
120ifeq ($(CONFIG_FUNCTION_TRACER),y) 123ifeq ($(CONFIG_FUNCTION_TRACER),y)
121ORIG_CFLAGS := $(KBUILD_CFLAGS) 124ORIG_CFLAGS := $(KBUILD_CFLAGS)
@@ -151,6 +154,12 @@ lib1funcs = $(obj)/lib1funcs.o
151$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S 154$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
152 $(call cmd,shipped) 155 $(call cmd,shipped)
153 156
157# For __aeabi_llsl
158ashldi3 = $(obj)/ashldi3.o
159
160$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
161 $(call cmd,shipped)
162
154# We need to prevent any GOTOFF relocs being used with references 163# We need to prevent any GOTOFF relocs being used with references
155# to symbols in the .bss section since we cannot relocate them 164# to symbols in the .bss section since we cannot relocate them
156# independently from the rest at run time. This can be achieved by 165# independently from the rest at run time. This can be achieved by
@@ -172,7 +181,7 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
172fi 181fi
173 182
174$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ 183$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
175 $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE 184 $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE
176 @$(check_for_multiple_zreladdr) 185 @$(check_for_multiple_zreladdr)
177 $(call if_changed,ld) 186 $(call if_changed,ld)
178 @$(check_for_bad_syms) 187 @$(check_for_bad_syms)
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
index 07be5a2f830..f41b38cafce 100644
--- a/arch/arm/boot/compressed/decompress.c
+++ b/arch/arm/boot/compressed/decompress.c
@@ -44,6 +44,12 @@ extern void error(char *);
44#include "../../../../lib/decompress_unlzma.c" 44#include "../../../../lib/decompress_unlzma.c"
45#endif 45#endif
46 46
47#ifdef CONFIG_KERNEL_XZ
48#define memmove memmove
49#define memcpy memcpy
50#include "../../../../lib/decompress_unxz.c"
51#endif
52
47int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) 53int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
48{ 54{
49 return decompress(input, len, NULL, NULL, output, NULL, error); 55 return decompress(input, len, NULL, NULL, output, NULL, error);
diff --git a/arch/arm/boot/compressed/piggy.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S
new file mode 100644
index 00000000000..5703f300d02
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.xzkern.S
@@ -0,0 +1,6 @@
1 .section .piggydata,#alloc
2 .globl input_data
3input_data:
4 .incbin "arch/arm/boot/compressed/piggy.xzkern"
5 .globl input_data_end
6input_data_end:
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index f0783be1735..aa526998418 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -686,13 +686,12 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
686 * For primary GICs, skip over SGIs. 686 * For primary GICs, skip over SGIs.
687 * For secondary GICs, skip over PPIs, too. 687 * For secondary GICs, skip over PPIs, too.
688 */ 688 */
689 hwirq_base = 32; 689 if (gic_nr == 0 && (irq_start & 31) > 0) {
690 if (gic_nr == 0) { 690 hwirq_base = 16;
691 if ((irq_start & 31) > 0) { 691 if (irq_start != -1)
692 hwirq_base = 16; 692 irq_start = (irq_start & ~31) + 16;
693 if (irq_start != -1) 693 } else {
694 irq_start = (irq_start & ~31) + 16; 694 hwirq_base = 32;
695 }
696 } 695 }
697 696
698 /* 697 /*
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index 1103f62a196..a8314c3ee84 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -57,18 +57,24 @@ CONFIG_NETDEVICES=y
57CONFIG_NET_ETHERNET=y 57CONFIG_NET_ETHERNET=y
58CONFIG_NET_PCI=y 58CONFIG_NET_PCI=y
59CONFIG_E100=y 59CONFIG_E100=y
60CONFIG_SMC91X=y
60# CONFIG_KEYBOARD_ATKBD is not set 61# CONFIG_KEYBOARD_ATKBD is not set
61# CONFIG_SERIO_SERPORT is not set 62# CONFIG_SERIO_SERPORT is not set
62CONFIG_SERIAL_AMBA_PL010=y 63CONFIG_SERIAL_AMBA_PL010=y
63CONFIG_SERIAL_AMBA_PL010_CONSOLE=y 64CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
64CONFIG_FB=y 65CONFIG_FB=y
65CONFIG_FB_MODE_HELPERS=y 66CONFIG_FB_MODE_HELPERS=y
67CONFIG_FB_ARMCLCD=y
66CONFIG_FB_MATROX=y 68CONFIG_FB_MATROX=y
67CONFIG_FB_MATROX_MILLENIUM=y 69CONFIG_FB_MATROX_MILLENIUM=y
68CONFIG_FB_MATROX_MYSTIQUE=y 70CONFIG_FB_MATROX_MYSTIQUE=y
71# CONFIG_VGA_CONSOLE is not set
72CONFIG_MMC=y
73CONFIG_MMC_ARMMMCI=y
69CONFIG_RTC_CLASS=y 74CONFIG_RTC_CLASS=y
70CONFIG_RTC_DRV_PL030=y 75CONFIG_RTC_DRV_PL030=y
71CONFIG_EXT2_FS=y 76CONFIG_EXT2_FS=y
77CONFIG_VFAT_FS=y
72CONFIG_TMPFS=y 78CONFIG_TMPFS=y
73CONFIG_JFFS2_FS=y 79CONFIG_JFFS2_FS=y
74CONFIG_CRAMFS=y 80CONFIG_CRAMFS=y
@@ -78,5 +84,7 @@ CONFIG_ROOT_NFS=y
78CONFIG_NFSD=y 84CONFIG_NFSD=y
79CONFIG_NFSD_V3=y 85CONFIG_NFSD_V3=y
80CONFIG_PARTITION_ADVANCED=y 86CONFIG_PARTITION_ADVANCED=y
87CONFIG_NLS_CODEPAGE_437=y
88CONFIG_NLS_ISO8859_1=y
81CONFIG_MAGIC_SYSRQ=y 89CONFIG_MAGIC_SYSRQ=y
82CONFIG_DEBUG_KERNEL=y 90CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 0e9ce8d9686..38050b1c480 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -130,8 +130,4 @@ struct mm_struct;
130extern unsigned long arch_randomize_brk(struct mm_struct *mm); 130extern unsigned long arch_randomize_brk(struct mm_struct *mm);
131#define arch_randomize_brk arch_randomize_brk 131#define arch_randomize_brk arch_randomize_brk
132 132
133extern int vectors_user_mapping(void);
134#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
135#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
136
137#endif 133#endif
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 7df239bcdf2..c4c87bc1223 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -103,11 +103,11 @@
103#define L2X0_ADDR_FILTER_EN 1 103#define L2X0_ADDR_FILTER_EN 1
104 104
105#ifndef __ASSEMBLY__ 105#ifndef __ASSEMBLY__
106extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); 106extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
107#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF) 107#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
108extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask); 108extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
109#else 109#else
110static inline int l2x0_of_init(__u32 aux_val, __u32 aux_mask) 110static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
111{ 111{
112 return -ENODEV; 112 return -ENODEV;
113} 113}
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h
index 43cab498bc2..73f84fa4f36 100644
--- a/arch/arm/include/asm/hardware/it8152.h
+++ b/arch/arm/include/asm/hardware/it8152.h
@@ -9,6 +9,9 @@
9 9
10#ifndef __ASM_HARDWARE_IT8152_H 10#ifndef __ASM_HARDWARE_IT8152_H
11#define __ASM_HARDWARE_IT8152_H 11#define __ASM_HARDWARE_IT8152_H
12
13#include <mach/irqs.h>
14
12extern void __iomem *it8152_base_address; 15extern void __iomem *it8152_base_address;
13 16
14#define IT8152_IO_BASE (it8152_base_address + 0x03e00000) 17#define IT8152_IO_BASE (it8152_base_address + 0x03e00000)
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 5a526afb5f1..35c21c375d8 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -1,14 +1,18 @@
1#ifndef __ASM_ARM_IRQ_H 1#ifndef __ASM_ARM_IRQ_H
2#define __ASM_ARM_IRQ_H 2#define __ASM_ARM_IRQ_H
3 3
4#define NR_IRQS_LEGACY 16
5
6#ifndef CONFIG_SPARSE_IRQ
4#include <mach/irqs.h> 7#include <mach/irqs.h>
8#else
9#define NR_IRQS NR_IRQS_LEGACY
10#endif
5 11
6#ifndef irq_canonicalize 12#ifndef irq_canonicalize
7#define irq_canonicalize(i) (i) 13#define irq_canonicalize(i) (i)
8#endif 14#endif
9 15
10#define NR_IRQS_LEGACY 16
11
12/* 16/*
13 * Use this value to indicate lack of interrupt 17 * Use this value to indicate lack of interrupt
14 * capability 18 * capability
diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h
new file mode 100644
index 00000000000..5c5ca2ea62b
--- /dev/null
+++ b/arch/arm/include/asm/jump_label.h
@@ -0,0 +1,41 @@
1#ifndef _ASM_ARM_JUMP_LABEL_H
2#define _ASM_ARM_JUMP_LABEL_H
3
4#ifdef __KERNEL__
5
6#include <linux/types.h>
7#include <asm/system.h>
8
9#define JUMP_LABEL_NOP_SIZE 4
10
11#ifdef CONFIG_THUMB2_KERNEL
12#define JUMP_LABEL_NOP "nop.w"
13#else
14#define JUMP_LABEL_NOP "nop"
15#endif
16
17static __always_inline bool arch_static_branch(struct jump_label_key *key)
18{
19 asm goto("1:\n\t"
20 JUMP_LABEL_NOP "\n\t"
21 ".pushsection __jump_table, \"aw\"\n\t"
22 ".word 1b, %l[l_yes], %c0\n\t"
23 ".popsection\n\t"
24 : : "i" (key) : : l_yes);
25
26 return false;
27l_yes:
28 return true;
29}
30
31#endif /* __KERNEL__ */
32
33typedef u32 jump_label_t;
34
35struct jump_entry {
36 jump_label_t code;
37 jump_label_t target;
38 jump_label_t key;
39};
40
41#endif
diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h
index 6b884d2b0b6..e8567bb99df 100644
--- a/arch/arm/include/asm/mc146818rtc.h
+++ b/arch/arm/include/asm/mc146818rtc.h
@@ -5,7 +5,9 @@
5#define _ASM_MC146818RTC_H 5#define _ASM_MC146818RTC_H
6 6
7#include <linux/io.h> 7#include <linux/io.h>
8#include <mach/irqs.h> 8#include <linux/kernel.h>
9
10#define RTC_IRQ BUILD_BUG_ON(1)
9 11
10#ifndef RTC_PORT 12#ifndef RTC_PORT
11#define RTC_PORT(x) (0x70 + (x)) 13#define RTC_PORT(x) (0x70 + (x))
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index a8997d71084..fcb575747e5 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -116,6 +116,8 @@
116#define MODULES_END (END_MEM) 116#define MODULES_END (END_MEM)
117#define MODULES_VADDR (PHYS_OFFSET) 117#define MODULES_VADDR (PHYS_OFFSET)
118 118
119#define XIP_VIRT_ADDR(physaddr) (physaddr)
120
119#endif /* !CONFIG_MMU */ 121#endif /* !CONFIG_MMU */
120 122
121/* 123/*
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 71605d9f8e4..a0b3cac0547 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -18,6 +18,7 @@
18#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
19#include <asm/cachetype.h> 19#include <asm/cachetype.h>
20#include <asm/proc-fns.h> 20#include <asm/proc-fns.h>
21#include <asm-generic/mm_hooks.h>
21 22
22void __check_kvm_seq(struct mm_struct *mm); 23void __check_kvm_seq(struct mm_struct *mm);
23 24
@@ -133,32 +134,4 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
133#define deactivate_mm(tsk,mm) do { } while (0) 134#define deactivate_mm(tsk,mm) do { } while (0)
134#define activate_mm(prev,next) switch_mm(prev, next, NULL) 135#define activate_mm(prev,next) switch_mm(prev, next, NULL)
135 136
136/*
137 * We are inserting a "fake" vma for the user-accessible vector page so
138 * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
139 * But we also want to remove it before the generic code gets to see it
140 * during process exit or the unmapping of it would cause total havoc.
141 * (the macro is used as remove_vma() is static to mm/mmap.c)
142 */
143#define arch_exit_mmap(mm) \
144do { \
145 struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
146 if (high_vma) { \
147 BUG_ON(high_vma->vm_next); /* it should be last */ \
148 if (high_vma->vm_prev) \
149 high_vma->vm_prev->vm_next = NULL; \
150 else \
151 mm->mmap = NULL; \
152 rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
153 mm->mmap_cache = NULL; \
154 mm->map_count--; \
155 remove_vma(high_vma); \
156 } \
157} while (0)
158
159static inline void arch_dup_mmap(struct mm_struct *oldmm,
160 struct mm_struct *mm)
161{
162}
163
164#endif 137#endif
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
index c0efdd60966..19c48deda70 100644
--- a/arch/arm/include/asm/opcodes.h
+++ b/arch/arm/include/asm/opcodes.h
@@ -17,4 +17,63 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
17#define ARM_OPCODE_CONDTEST_PASS 1 17#define ARM_OPCODE_CONDTEST_PASS 1
18#define ARM_OPCODE_CONDTEST_UNCOND 2 18#define ARM_OPCODE_CONDTEST_UNCOND 2
19 19
20
21/*
22 * Opcode byteswap helpers
23 *
24 * These macros help with converting instructions between a canonical integer
25 * format and in-memory representation, in an endianness-agnostic manner.
26 *
27 * __mem_to_opcode_*() convert from in-memory representation to canonical form.
28 * __opcode_to_mem_*() convert from canonical form to in-memory representation.
29 *
30 *
31 * Canonical instruction representation:
32 *
33 * ARM: 0xKKLLMMNN
34 * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8
35 * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8
36 *
37 * There is no way to distinguish an ARM instruction in canonical representation
38 * from a Thumb instruction (just as these cannot be distinguished in memory).
39 * Where this distinction is important, it needs to be tracked separately.
40 *
41 * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
42 * represent any valid Thumb-2 instruction. For this range,
43 * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
44 */
45
46#ifndef __ASSEMBLY__
47
48#include <linux/types.h>
49#include <linux/swab.h>
50
51#ifdef CONFIG_CPU_ENDIAN_BE8
52#define __opcode_to_mem_arm(x) swab32(x)
53#define __opcode_to_mem_thumb16(x) swab16(x)
54#define __opcode_to_mem_thumb32(x) swahb32(x)
55#else
56#define __opcode_to_mem_arm(x) ((u32)(x))
57#define __opcode_to_mem_thumb16(x) ((u16)(x))
58#define __opcode_to_mem_thumb32(x) swahw32(x)
59#endif
60
61#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
62#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
63#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
64
65/* Operations specific to Thumb opcodes */
66
67/* Instruction size checks: */
68#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL)
69#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL)
70
71/* Operations to construct or split 32-bit Thumb instructions: */
72#define __opcode_thumb32_first(x) ((u16)((x) >> 16))
73#define __opcode_thumb32_second(x) ((u16)(x))
74#define __opcode_thumb32_compose(first, second) \
75 (((u32)(u16)(first) << 16) | (u32)(u16)(second))
76
77#endif /* __ASSEMBLY__ */
78
20#endif /* __ASM_ARM_OPCODES_H */ 79#endif /* __ASM_ARM_OPCODES_H */
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 97b440c25c5..5838361c48b 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -151,6 +151,8 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
151#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) 151#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
152extern void copy_page(void *to, const void *from); 152extern void copy_page(void *to, const void *from);
153 153
154#define __HAVE_ARCH_GATE_AREA 1
155
154#ifdef CONFIG_ARM_LPAE 156#ifdef CONFIG_ARM_LPAE
155#include <asm/pgtable-3level-types.h> 157#include <asm/pgtable-3level-types.h>
156#else 158#else
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index 7523340afb8..00cbe10a50e 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -22,6 +22,7 @@ enum arm_perf_pmu_ids {
22 ARM_PERF_PMU_ID_CA9, 22 ARM_PERF_PMU_ID_CA9,
23 ARM_PERF_PMU_ID_CA5, 23 ARM_PERF_PMU_ID_CA5,
24 ARM_PERF_PMU_ID_CA15, 24 ARM_PERF_PMU_ID_CA15,
25 ARM_PERF_PMU_ID_CA7,
25 ARM_NUM_PMU_IDS, 26 ARM_NUM_PMU_IDS,
26}; 27};
27 28
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index f4d7f56ee51..5ac8d3d3e02 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -55,7 +55,6 @@ struct thread_struct {
55#define start_thread(regs,pc,sp) \ 55#define start_thread(regs,pc,sp) \
56({ \ 56({ \
57 unsigned long *stack = (unsigned long *)sp; \ 57 unsigned long *stack = (unsigned long *)sp; \
58 set_fs(USER_DS); \
59 memset(regs->uregs, 0, sizeof(regs->uregs)); \ 58 memset(regs->uregs, 0, sizeof(regs->uregs)); \
60 if (current->personality & ADDR_LIMIT_32BIT) \ 59 if (current->personality & ADDR_LIMIT_32BIT) \
61 regs->ARM_cpsr = USR_MODE; \ 60 regs->ARM_cpsr = USR_MODE; \
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
index ee036330791..aeae9c609df 100644
--- a/arch/arm/include/asm/prom.h
+++ b/arch/arm/include/asm/prom.h
@@ -13,8 +13,6 @@
13 13
14#ifdef CONFIG_OF 14#ifdef CONFIG_OF
15 15
16#include <asm/irq.h>
17
18extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); 16extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
19extern void arm_dt_memblock_reserve(void); 17extern void arm_dt_memblock_reserve(void);
20 18
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 02b2f820398..85fe61e7320 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -318,6 +318,21 @@ extern struct cpu_tlb_fns cpu_tlb;
318 318
319#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) 319#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
320 320
321#define __tlb_op(f, insnarg, arg) \
322 do { \
323 if (always_tlb_flags & (f)) \
324 asm("mcr " insnarg \
325 : : "r" (arg) : "cc"); \
326 else if (possible_tlb_flags & (f)) \
327 asm("tst %1, %2\n\t" \
328 "mcrne " insnarg \
329 : : "r" (arg), "r" (__tlb_flag), "Ir" (f) \
330 : "cc"); \
331 } while (0)
332
333#define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg)
334#define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg)
335
321static inline void local_flush_tlb_all(void) 336static inline void local_flush_tlb_all(void)
322{ 337{
323 const int zero = 0; 338 const int zero = 0;
@@ -326,16 +341,11 @@ static inline void local_flush_tlb_all(void)
326 if (tlb_flag(TLB_WB)) 341 if (tlb_flag(TLB_WB))
327 dsb(); 342 dsb();
328 343
329 if (tlb_flag(TLB_V3_FULL)) 344 tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
330 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); 345 tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero);
331 if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) 346 tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero);
332 asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); 347 tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero);
333 if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) 348 tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero);
334 asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
335 if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
336 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
337 if (tlb_flag(TLB_V7_UIS_FULL))
338 asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
339 349
340 if (tlb_flag(TLB_BARRIER)) { 350 if (tlb_flag(TLB_BARRIER)) {
341 dsb(); 351 dsb();
@@ -352,29 +362,23 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
352 if (tlb_flag(TLB_WB)) 362 if (tlb_flag(TLB_WB))
353 dsb(); 363 dsb();
354 364
355 if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { 365 if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) {
356 if (tlb_flag(TLB_V3_FULL)) 366 if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
357 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); 367 tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
358 if (tlb_flag(TLB_V4_U_FULL)) 368 tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero);
359 asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); 369 tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero);
360 if (tlb_flag(TLB_V4_D_FULL)) 370 tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero);
361 asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); 371 }
362 if (tlb_flag(TLB_V4_I_FULL)) 372 put_cpu();
363 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
364 } 373 }
365 put_cpu(); 374
366 375 tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid);
367 if (tlb_flag(TLB_V6_U_ASID)) 376 tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid);
368 asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc"); 377 tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid);
369 if (tlb_flag(TLB_V6_D_ASID))
370 asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
371 if (tlb_flag(TLB_V6_I_ASID))
372 asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
373 if (tlb_flag(TLB_V7_UIS_ASID))
374#ifdef CONFIG_ARM_ERRATA_720789 378#ifdef CONFIG_ARM_ERRATA_720789
375 asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); 379 tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", zero);
376#else 380#else
377 asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); 381 tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", asid);
378#endif 382#endif
379 383
380 if (tlb_flag(TLB_BARRIER)) 384 if (tlb_flag(TLB_BARRIER))
@@ -392,30 +396,23 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
392 if (tlb_flag(TLB_WB)) 396 if (tlb_flag(TLB_WB))
393 dsb(); 397 dsb();
394 398
395 if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { 399 if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) &&
396 if (tlb_flag(TLB_V3_PAGE)) 400 cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
397 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc"); 401 tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr);
398 if (tlb_flag(TLB_V4_U_PAGE)) 402 tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr);
399 asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); 403 tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr);
400 if (tlb_flag(TLB_V4_D_PAGE)) 404 tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr);
401 asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
402 if (tlb_flag(TLB_V4_I_PAGE))
403 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
404 if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) 405 if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
405 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); 406 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
406 } 407 }
407 408
408 if (tlb_flag(TLB_V6_U_PAGE)) 409 tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr);
409 asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); 410 tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr);
410 if (tlb_flag(TLB_V6_D_PAGE)) 411 tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr);
411 asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
412 if (tlb_flag(TLB_V6_I_PAGE))
413 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
414 if (tlb_flag(TLB_V7_UIS_PAGE))
415#ifdef CONFIG_ARM_ERRATA_720789 412#ifdef CONFIG_ARM_ERRATA_720789
416 asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc"); 413 tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK);
417#else 414#else
418 asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); 415 tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", uaddr);
419#endif 416#endif
420 417
421 if (tlb_flag(TLB_BARRIER)) 418 if (tlb_flag(TLB_BARRIER))
@@ -432,25 +429,17 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
432 if (tlb_flag(TLB_WB)) 429 if (tlb_flag(TLB_WB))
433 dsb(); 430 dsb();
434 431
435 if (tlb_flag(TLB_V3_PAGE)) 432 tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr);
436 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); 433 tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr);
437 if (tlb_flag(TLB_V4_U_PAGE)) 434 tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr);
438 asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); 435 tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr);
439 if (tlb_flag(TLB_V4_D_PAGE))
440 asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
441 if (tlb_flag(TLB_V4_I_PAGE))
442 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
443 if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) 436 if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
444 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); 437 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
445 438
446 if (tlb_flag(TLB_V6_U_PAGE)) 439 tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr);
447 asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); 440 tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr);
448 if (tlb_flag(TLB_V6_D_PAGE)) 441 tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr);
449 asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); 442 tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr);
450 if (tlb_flag(TLB_V6_I_PAGE))
451 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
452 if (tlb_flag(TLB_V7_UIS_PAGE))
453 asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
454 443
455 if (tlb_flag(TLB_BARRIER)) { 444 if (tlb_flag(TLB_BARRIER)) {
456 dsb(); 445 dsb();
@@ -475,13 +464,8 @@ static inline void flush_pmd_entry(void *pmd)
475{ 464{
476 const unsigned int __tlb_flag = __cpu_tlb_flags; 465 const unsigned int __tlb_flag = __cpu_tlb_flags;
477 466
478 if (tlb_flag(TLB_DCLEAN)) 467 tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd);
479 asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" 468 tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd);
480 : : "r" (pmd) : "cc");
481
482 if (tlb_flag(TLB_L2CLEAN_FR))
483 asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd"
484 : : "r" (pmd) : "cc");
485 469
486 if (tlb_flag(TLB_WB)) 470 if (tlb_flag(TLB_WB))
487 dsb(); 471 dsb();
@@ -491,15 +475,11 @@ static inline void clean_pmd_entry(void *pmd)
491{ 475{
492 const unsigned int __tlb_flag = __cpu_tlb_flags; 476 const unsigned int __tlb_flag = __cpu_tlb_flags;
493 477
494 if (tlb_flag(TLB_DCLEAN)) 478 tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd);
495 asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" 479 tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd);
496 : : "r" (pmd) : "cc");
497
498 if (tlb_flag(TLB_L2CLEAN_FR))
499 asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd"
500 : : "r" (pmd) : "cc");
501} 480}
502 481
482#undef tlb_op
503#undef tlb_flag 483#undef tlb_flag
504#undef always_tlb_flags 484#undef always_tlb_flags
505#undef possible_tlb_flags 485#undef possible_tlb_flags
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
index 5b29a667362..f555bb3664d 100644
--- a/arch/arm/include/asm/traps.h
+++ b/arch/arm/include/asm/traps.h
@@ -46,7 +46,7 @@ static inline int in_exception_text(unsigned long ptr)
46 return in ? : __in_irqentry_text(ptr); 46 return in ? : __in_irqentry_text(ptr);
47} 47}
48 48
49extern void __init early_trap_init(void); 49extern void __init early_trap_init(void *);
50extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); 50extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
51extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); 51extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs);
52 52
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 3a274878412..8269d892874 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -7,6 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
7 7
8ifdef CONFIG_FUNCTION_TRACER 8ifdef CONFIG_FUNCTION_TRACER
9CFLAGS_REMOVE_ftrace.o = -pg 9CFLAGS_REMOVE_ftrace.o = -pg
10CFLAGS_REMOVE_insn.o = -pg
11CFLAGS_REMOVE_patch.o = -pg
10endif 12endif
11 13
12CFLAGS_REMOVE_return_address.o = -pg 14CFLAGS_REMOVE_return_address.o = -pg
@@ -14,8 +16,8 @@ CFLAGS_REMOVE_return_address.o = -pg
14# Object file lists. 16# Object file lists.
15 17
16obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ 18obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
17 process.o ptrace.o return_address.o setup.o signal.o \ 19 process.o ptrace.o return_address.o sched_clock.o \
18 sys_arm.o stacktrace.o time.o traps.o 20 setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
19 21
20obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o 22obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
21 23
@@ -29,14 +31,14 @@ obj-$(CONFIG_ARTHUR) += arthur.o
29obj-$(CONFIG_ISA_DMA) += dma-isa.o 31obj-$(CONFIG_ISA_DMA) += dma-isa.o
30obj-$(CONFIG_PCI) += bios32.o isa.o 32obj-$(CONFIG_PCI) += bios32.o isa.o
31obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o 33obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o
32obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
33obj-$(CONFIG_SMP) += smp.o smp_tlb.o 34obj-$(CONFIG_SMP) += smp.o smp_tlb.o
34obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
35obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o 36obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
36obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 37obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
37obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 38obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
39obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
38obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 40obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
39obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o 41obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o
40ifdef CONFIG_THUMB2_KERNEL 42ifdef CONFIG_THUMB2_KERNEL
41obj-$(CONFIG_KPROBES) += kprobes-thumb.o 43obj-$(CONFIG_KPROBES) += kprobes-thumb.o
42else 44else
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index 204e2160cfc..e5a765c5f06 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -100,7 +100,7 @@
100 100
101#endif /* CONFIG_CPU_V6 */ 101#endif /* CONFIG_CPU_V6 */
102 102
103#else 103#elif !defined(CONFIG_DEBUG_SEMIHOSTING)
104#include <mach/debug-macro.S> 104#include <mach/debug-macro.S>
105#endif /* CONFIG_DEBUG_ICEDCC */ 105#endif /* CONFIG_DEBUG_ICEDCC */
106 106
@@ -155,6 +155,8 @@ hexbuf: .space 16
155 155
156 .ltorg 156 .ltorg
157 157
158#ifndef CONFIG_DEBUG_SEMIHOSTING
159
158ENTRY(printascii) 160ENTRY(printascii)
159 addruart_current r3, r1, r2 161 addruart_current r3, r1, r2
160 b 2f 162 b 2f
@@ -177,3 +179,24 @@ ENTRY(printch)
177 mov r0, #0 179 mov r0, #0
178 b 1b 180 b 1b
179ENDPROC(printch) 181ENDPROC(printch)
182
183#else
184
185ENTRY(printascii)
186 mov r1, r0
187 mov r0, #0x04 @ SYS_WRITE0
188 ARM( svc #0x123456 )
189 THUMB( svc #0xab )
190 mov pc, lr
191ENDPROC(printascii)
192
193ENTRY(printch)
194 adr r1, hexbuf
195 strb r0, [r1]
196 mov r0, #0x03 @ SYS_WRITEC
197 ARM( svc #0x123456 )
198 THUMB( svc #0xab )
199 mov pc, lr
200ENDPROC(printch)
201
202#endif
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index c0062ad1e84..df0bf0c8cb7 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -16,10 +16,13 @@
16#include <linux/uaccess.h> 16#include <linux/uaccess.h>
17 17
18#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
19#include <asm/opcodes.h>
19#include <asm/ftrace.h> 20#include <asm/ftrace.h>
20 21
22#include "insn.h"
23
21#ifdef CONFIG_THUMB2_KERNEL 24#ifdef CONFIG_THUMB2_KERNEL
22#define NOP 0xeb04f85d /* pop.w {lr} */ 25#define NOP 0xf85deb04 /* pop.w {lr} */
23#else 26#else
24#define NOP 0xe8bd4000 /* pop {lr} */ 27#define NOP 0xe8bd4000 /* pop {lr} */
25#endif 28#endif
@@ -60,76 +63,31 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
60} 63}
61#endif 64#endif
62 65
63#ifdef CONFIG_THUMB2_KERNEL
64static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
65 bool link)
66{
67 unsigned long s, j1, j2, i1, i2, imm10, imm11;
68 unsigned long first, second;
69 long offset;
70
71 offset = (long)addr - (long)(pc + 4);
72 if (offset < -16777216 || offset > 16777214) {
73 WARN_ON_ONCE(1);
74 return 0;
75 }
76
77 s = (offset >> 24) & 0x1;
78 i1 = (offset >> 23) & 0x1;
79 i2 = (offset >> 22) & 0x1;
80 imm10 = (offset >> 12) & 0x3ff;
81 imm11 = (offset >> 1) & 0x7ff;
82
83 j1 = (!i1) ^ s;
84 j2 = (!i2) ^ s;
85
86 first = 0xf000 | (s << 10) | imm10;
87 second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
88 if (link)
89 second |= 1 << 14;
90
91 return (second << 16) | first;
92}
93#else
94static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
95 bool link)
96{
97 unsigned long opcode = 0xea000000;
98 long offset;
99
100 if (link)
101 opcode |= 1 << 24;
102
103 offset = (long)addr - (long)(pc + 8);
104 if (unlikely(offset < -33554432 || offset > 33554428)) {
105 /* Can't generate branches that far (from ARM ARM). Ftrace
106 * doesn't generate branches outside of kernel text.
107 */
108 WARN_ON_ONCE(1);
109 return 0;
110 }
111
112 offset = (offset >> 2) & 0x00ffffff;
113
114 return opcode | offset;
115}
116#endif
117
118static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) 66static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
119{ 67{
120 return ftrace_gen_branch(pc, addr, true); 68 return arm_gen_branch_link(pc, addr);
121} 69}
122 70
123static int ftrace_modify_code(unsigned long pc, unsigned long old, 71static int ftrace_modify_code(unsigned long pc, unsigned long old,
124 unsigned long new) 72 unsigned long new, bool validate)
125{ 73{
126 unsigned long replaced; 74 unsigned long replaced;
127 75
128 if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) 76 if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
129 return -EFAULT; 77 old = __opcode_to_mem_thumb32(old);
78 new = __opcode_to_mem_thumb32(new);
79 } else {
80 old = __opcode_to_mem_arm(old);
81 new = __opcode_to_mem_arm(new);
82 }
130 83
131 if (replaced != old) 84 if (validate) {
132 return -EINVAL; 85 if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
86 return -EFAULT;
87
88 if (replaced != old)
89 return -EINVAL;
90 }
133 91
134 if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE)) 92 if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE))
135 return -EPERM; 93 return -EPERM;
@@ -141,23 +99,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
141 99
142int ftrace_update_ftrace_func(ftrace_func_t func) 100int ftrace_update_ftrace_func(ftrace_func_t func)
143{ 101{
144 unsigned long pc, old; 102 unsigned long pc;
145 unsigned long new; 103 unsigned long new;
146 int ret; 104 int ret;
147 105
148 pc = (unsigned long)&ftrace_call; 106 pc = (unsigned long)&ftrace_call;
149 memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
150 new = ftrace_call_replace(pc, (unsigned long)func); 107 new = ftrace_call_replace(pc, (unsigned long)func);
151 108
152 ret = ftrace_modify_code(pc, old, new); 109 ret = ftrace_modify_code(pc, 0, new, false);
153 110
154#ifdef CONFIG_OLD_MCOUNT 111#ifdef CONFIG_OLD_MCOUNT
155 if (!ret) { 112 if (!ret) {
156 pc = (unsigned long)&ftrace_call_old; 113 pc = (unsigned long)&ftrace_call_old;
157 memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE);
158 new = ftrace_call_replace(pc, (unsigned long)func); 114 new = ftrace_call_replace(pc, (unsigned long)func);
159 115
160 ret = ftrace_modify_code(pc, old, new); 116 ret = ftrace_modify_code(pc, 0, new, false);
161 } 117 }
162#endif 118#endif
163 119
@@ -172,7 +128,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
172 old = ftrace_nop_replace(rec); 128 old = ftrace_nop_replace(rec);
173 new = ftrace_call_replace(ip, adjust_address(rec, addr)); 129 new = ftrace_call_replace(ip, adjust_address(rec, addr));
174 130
175 return ftrace_modify_code(rec->ip, old, new); 131 return ftrace_modify_code(rec->ip, old, new, true);
176} 132}
177 133
178int ftrace_make_nop(struct module *mod, 134int ftrace_make_nop(struct module *mod,
@@ -185,7 +141,7 @@ int ftrace_make_nop(struct module *mod,
185 141
186 old = ftrace_call_replace(ip, adjust_address(rec, addr)); 142 old = ftrace_call_replace(ip, adjust_address(rec, addr));
187 new = ftrace_nop_replace(rec); 143 new = ftrace_nop_replace(rec);
188 ret = ftrace_modify_code(ip, old, new); 144 ret = ftrace_modify_code(ip, old, new, true);
189 145
190#ifdef CONFIG_OLD_MCOUNT 146#ifdef CONFIG_OLD_MCOUNT
191 if (ret == -EINVAL && addr == MCOUNT_ADDR) { 147 if (ret == -EINVAL && addr == MCOUNT_ADDR) {
@@ -193,7 +149,7 @@ int ftrace_make_nop(struct module *mod,
193 149
194 old = ftrace_call_replace(ip, adjust_address(rec, addr)); 150 old = ftrace_call_replace(ip, adjust_address(rec, addr));
195 new = ftrace_nop_replace(rec); 151 new = ftrace_nop_replace(rec);
196 ret = ftrace_modify_code(ip, old, new); 152 ret = ftrace_modify_code(ip, old, new, true);
197 } 153 }
198#endif 154#endif
199 155
@@ -249,12 +205,12 @@ static int __ftrace_modify_caller(unsigned long *callsite,
249{ 205{
250 unsigned long caller_fn = (unsigned long) func; 206 unsigned long caller_fn = (unsigned long) func;
251 unsigned long pc = (unsigned long) callsite; 207 unsigned long pc = (unsigned long) callsite;
252 unsigned long branch = ftrace_gen_branch(pc, caller_fn, false); 208 unsigned long branch = arm_gen_branch(pc, caller_fn);
253 unsigned long nop = 0xe1a00000; /* mov r0, r0 */ 209 unsigned long nop = 0xe1a00000; /* mov r0, r0 */
254 unsigned long old = enable ? nop : branch; 210 unsigned long old = enable ? nop : branch;
255 unsigned long new = enable ? branch : nop; 211 unsigned long new = enable ? branch : nop;
256 212
257 return ftrace_modify_code(pc, old, new); 213 return ftrace_modify_code(pc, old, new, true);
258} 214}
259 215
260static int ftrace_modify_graph_caller(bool enable) 216static int ftrace_modify_graph_caller(bool enable)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index a2e9694a68e..3bf0c7f8b04 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -265,7 +265,7 @@ __create_page_tables:
265 str r6, [r3] 265 str r6, [r3]
266 266
267#ifdef CONFIG_DEBUG_LL 267#ifdef CONFIG_DEBUG_LL
268#ifndef CONFIG_DEBUG_ICEDCC 268#if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING)
269 /* 269 /*
270 * Map in IO space for serial debugging. 270 * Map in IO space for serial debugging.
271 * This allows debug messages to be output 271 * This allows debug messages to be output
@@ -297,10 +297,10 @@ __create_page_tables:
297 cmp r0, r6 297 cmp r0, r6
298 blo 1b 298 blo 1b
299 299
300#else /* CONFIG_DEBUG_ICEDCC */ 300#else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */
301 /* we don't need any serial debugging mappings for ICEDCC */ 301 /* we don't need any serial debugging mappings */
302 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags 302 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
303#endif /* !CONFIG_DEBUG_ICEDCC */ 303#endif
304 304
305#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) 305#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
306 /* 306 /*
diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c
new file mode 100644
index 00000000000..ab312e51654
--- /dev/null
+++ b/arch/arm/kernel/insn.c
@@ -0,0 +1,61 @@
1#include <linux/kernel.h>
2#include <asm/opcodes.h>
3
4static unsigned long
5__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link)
6{
7 unsigned long s, j1, j2, i1, i2, imm10, imm11;
8 unsigned long first, second;
9 long offset;
10
11 offset = (long)addr - (long)(pc + 4);
12 if (offset < -16777216 || offset > 16777214) {
13 WARN_ON_ONCE(1);
14 return 0;
15 }
16
17 s = (offset >> 24) & 0x1;
18 i1 = (offset >> 23) & 0x1;
19 i2 = (offset >> 22) & 0x1;
20 imm10 = (offset >> 12) & 0x3ff;
21 imm11 = (offset >> 1) & 0x7ff;
22
23 j1 = (!i1) ^ s;
24 j2 = (!i2) ^ s;
25
26 first = 0xf000 | (s << 10) | imm10;
27 second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
28 if (link)
29 second |= 1 << 14;
30
31 return __opcode_thumb32_compose(first, second);
32}
33
34static unsigned long
35__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link)
36{
37 unsigned long opcode = 0xea000000;
38 long offset;
39
40 if (link)
41 opcode |= 1 << 24;
42
43 offset = (long)addr - (long)(pc + 8);
44 if (unlikely(offset < -33554432 || offset > 33554428)) {
45 WARN_ON_ONCE(1);
46 return 0;
47 }
48
49 offset = (offset >> 2) & 0x00ffffff;
50
51 return opcode | offset;
52}
53
54unsigned long
55__arm_gen_branch(unsigned long pc, unsigned long addr, bool link)
56{
57 if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
58 return __arm_gen_branch_thumb2(pc, addr, link);
59 else
60 return __arm_gen_branch_arm(pc, addr, link);
61}
diff --git a/arch/arm/kernel/insn.h b/arch/arm/kernel/insn.h
new file mode 100644
index 00000000000..e96065da4da
--- /dev/null
+++ b/arch/arm/kernel/insn.h
@@ -0,0 +1,29 @@
1#ifndef __ASM_ARM_INSN_H
2#define __ASM_ARM_INSN_H
3
4static inline unsigned long
5arm_gen_nop(void)
6{
7#ifdef CONFIG_THUMB2_KERNEL
8 return 0xf3af8000; /* nop.w */
9#else
10 return 0xe1a00000; /* mov r0, r0 */
11#endif
12}
13
14unsigned long
15__arm_gen_branch(unsigned long pc, unsigned long addr, bool link);
16
17static inline unsigned long
18arm_gen_branch(unsigned long pc, unsigned long addr)
19{
20 return __arm_gen_branch(pc, addr, false);
21}
22
23static inline unsigned long
24arm_gen_branch_link(unsigned long pc, unsigned long addr)
25{
26 return __arm_gen_branch(pc, addr, true);
27}
28
29#endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 6a6a097edd6..71ccdbfed66 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -180,10 +180,7 @@ void migrate_irqs(void)
180 local_irq_save(flags); 180 local_irq_save(flags);
181 181
182 for_each_irq_desc(i, desc) { 182 for_each_irq_desc(i, desc) {
183 bool affinity_broken = false; 183 bool affinity_broken;
184
185 if (!desc)
186 continue;
187 184
188 raw_spin_lock(&desc->lock); 185 raw_spin_lock(&desc->lock);
189 affinity_broken = migrate_one_irq(desc); 186 affinity_broken = migrate_one_irq(desc);
diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c
new file mode 100644
index 00000000000..4ce4f789446
--- /dev/null
+++ b/arch/arm/kernel/jump_label.c
@@ -0,0 +1,39 @@
1#include <linux/kernel.h>
2#include <linux/jump_label.h>
3
4#include "insn.h"
5#include "patch.h"
6
7#ifdef HAVE_JUMP_LABEL
8
9static void __arch_jump_label_transform(struct jump_entry *entry,
10 enum jump_label_type type,
11 bool is_static)
12{
13 void *addr = (void *)entry->code;
14 unsigned int insn;
15
16 if (type == JUMP_LABEL_ENABLE)
17 insn = arm_gen_branch(entry->code, entry->target);
18 else
19 insn = arm_gen_nop();
20
21 if (is_static)
22 __patch_text(addr, insn);
23 else
24 patch_text(addr, insn);
25}
26
27void arch_jump_label_transform(struct jump_entry *entry,
28 enum jump_label_type type)
29{
30 __arch_jump_label_transform(entry, type, false);
31}
32
33void arch_jump_label_transform_static(struct jump_entry *entry,
34 enum jump_label_type type)
35{
36 __arch_jump_label_transform(entry, type, true);
37}
38
39#endif
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 129c1163248..ab1869dac97 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -29,6 +29,7 @@
29#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
30 30
31#include "kprobes.h" 31#include "kprobes.h"
32#include "patch.h"
32 33
33#define MIN_STACK_SIZE(addr) \ 34#define MIN_STACK_SIZE(addr) \
34 min((unsigned long)MAX_STACK_SIZE, \ 35 min((unsigned long)MAX_STACK_SIZE, \
@@ -103,57 +104,33 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
103 return 0; 104 return 0;
104} 105}
105 106
106#ifdef CONFIG_THUMB2_KERNEL
107
108/*
109 * For a 32-bit Thumb breakpoint spanning two memory words we need to take
110 * special precautions to insert the breakpoint atomically, especially on SMP
111 * systems. This is achieved by calling this arming function using stop_machine.
112 */
113static int __kprobes set_t32_breakpoint(void *addr)
114{
115 ((u16 *)addr)[0] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION >> 16;
116 ((u16 *)addr)[1] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION & 0xffff;
117 flush_insns(addr, 2*sizeof(u16));
118 return 0;
119}
120
121void __kprobes arch_arm_kprobe(struct kprobe *p) 107void __kprobes arch_arm_kprobe(struct kprobe *p)
122{ 108{
123 uintptr_t addr = (uintptr_t)p->addr & ~1; /* Remove any Thumb flag */ 109 unsigned int brkp;
124 110 void *addr;
125 if (!is_wide_instruction(p->opcode)) { 111
126 *(u16 *)addr = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION; 112 if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
127 flush_insns(addr, sizeof(u16)); 113 /* Remove any Thumb flag */
128 } else if (addr & 2) { 114 addr = (void *)((uintptr_t)p->addr & ~1);
129 /* A 32-bit instruction spanning two words needs special care */ 115
130 stop_machine(set_t32_breakpoint, (void *)addr, &cpu_online_map); 116 if (is_wide_instruction(p->opcode))
117 brkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION;
118 else
119 brkp = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION;
131 } else { 120 } else {
132 /* Word aligned 32-bit instruction can be written atomically */ 121 kprobe_opcode_t insn = p->opcode;
133 u32 bkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION;
134#ifndef __ARMEB__ /* Swap halfwords for little-endian */
135 bkp = (bkp >> 16) | (bkp << 16);
136#endif
137 *(u32 *)addr = bkp;
138 flush_insns(addr, sizeof(u32));
139 }
140}
141 122
142#else /* !CONFIG_THUMB2_KERNEL */ 123 addr = p->addr;
124 brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
143 125
144void __kprobes arch_arm_kprobe(struct kprobe *p) 126 if (insn >= 0xe0000000)
145{ 127 brkp |= 0xe0000000; /* Unconditional instruction */
146 kprobe_opcode_t insn = p->opcode; 128 else
147 kprobe_opcode_t brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION; 129 brkp |= insn & 0xf0000000; /* Copy condition from insn */
148 if (insn >= 0xe0000000) 130 }
149 brkp |= 0xe0000000; /* Unconditional instruction */
150 else
151 brkp |= insn & 0xf0000000; /* Copy condition from insn */
152 *p->addr = brkp;
153 flush_insns(p->addr, sizeof(p->addr[0]));
154}
155 131
156#endif /* !CONFIG_THUMB2_KERNEL */ 132 patch_text(addr, brkp);
133}
157 134
158/* 135/*
159 * The actual disarming is done here on each CPU and synchronized using 136 * The actual disarming is done here on each CPU and synchronized using
@@ -166,25 +143,10 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
166int __kprobes __arch_disarm_kprobe(void *p) 143int __kprobes __arch_disarm_kprobe(void *p)
167{ 144{
168 struct kprobe *kp = p; 145 struct kprobe *kp = p;
169#ifdef CONFIG_THUMB2_KERNEL 146 void *addr = (void *)((uintptr_t)kp->addr & ~1);
170 u16 *addr = (u16 *)((uintptr_t)kp->addr & ~1);
171 kprobe_opcode_t insn = kp->opcode;
172 unsigned int len;
173 147
174 if (is_wide_instruction(insn)) { 148 __patch_text(addr, kp->opcode);
175 ((u16 *)addr)[0] = insn>>16;
176 ((u16 *)addr)[1] = insn;
177 len = 2*sizeof(u16);
178 } else {
179 ((u16 *)addr)[0] = insn;
180 len = sizeof(u16);
181 }
182 flush_insns(addr, len);
183 149
184#else /* !CONFIG_THUMB2_KERNEL */
185 *kp->addr = kp->opcode;
186 flush_insns(kp->addr, sizeof(kp->addr[0]));
187#endif
188 return 0; 150 return 0;
189} 151}
190 152
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 56995983eed..dfcdb9f7c12 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -7,6 +7,7 @@
7#include <linux/delay.h> 7#include <linux/delay.h>
8#include <linux/reboot.h> 8#include <linux/reboot.h>
9#include <linux/io.h> 9#include <linux/io.h>
10#include <linux/irq.h>
10#include <asm/pgtable.h> 11#include <asm/pgtable.h>
11#include <asm/pgalloc.h> 12#include <asm/pgalloc.h>
12#include <asm/mmu_context.h> 13#include <asm/mmu_context.h>
@@ -53,6 +54,29 @@ void machine_crash_nonpanic_core(void *unused)
53 cpu_relax(); 54 cpu_relax();
54} 55}
55 56
57static void machine_kexec_mask_interrupts(void)
58{
59 unsigned int i;
60 struct irq_desc *desc;
61
62 for_each_irq_desc(i, desc) {
63 struct irq_chip *chip;
64
65 chip = irq_desc_get_chip(desc);
66 if (!chip)
67 continue;
68
69 if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
70 chip->irq_eoi(&desc->irq_data);
71
72 if (chip->irq_mask)
73 chip->irq_mask(&desc->irq_data);
74
75 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
76 chip->irq_disable(&desc->irq_data);
77 }
78}
79
56void machine_crash_shutdown(struct pt_regs *regs) 80void machine_crash_shutdown(struct pt_regs *regs)
57{ 81{
58 unsigned long msecs; 82 unsigned long msecs;
@@ -70,6 +94,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
70 printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n"); 94 printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
71 95
72 crash_save_cpu(regs, smp_processor_id()); 96 crash_save_cpu(regs, smp_processor_id());
97 machine_kexec_mask_interrupts();
73 98
74 printk(KERN_INFO "Loading crashdump kernel...\n"); 99 printk(KERN_INFO "Loading crashdump kernel...\n");
75} 100}
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
new file mode 100644
index 00000000000..07314af4773
--- /dev/null
+++ b/arch/arm/kernel/patch.c
@@ -0,0 +1,75 @@
1#include <linux/kernel.h>
2#include <linux/kprobes.h>
3#include <linux/stop_machine.h>
4
5#include <asm/cacheflush.h>
6#include <asm/smp_plat.h>
7#include <asm/opcodes.h>
8
9#include "patch.h"
10
11struct patch {
12 void *addr;
13 unsigned int insn;
14};
15
16void __kprobes __patch_text(void *addr, unsigned int insn)
17{
18 bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
19 int size;
20
21 if (thumb2 && __opcode_is_thumb16(insn)) {
22 *(u16 *)addr = __opcode_to_mem_thumb16(insn);
23 size = sizeof(u16);
24 } else if (thumb2 && ((uintptr_t)addr & 2)) {
25 u16 first = __opcode_thumb32_first(insn);
26 u16 second = __opcode_thumb32_second(insn);
27 u16 *addrh = addr;
28
29 addrh[0] = __opcode_to_mem_thumb16(first);
30 addrh[1] = __opcode_to_mem_thumb16(second);
31
32 size = sizeof(u32);
33 } else {
34 if (thumb2)
35 insn = __opcode_to_mem_thumb32(insn);
36 else
37 insn = __opcode_to_mem_arm(insn);
38
39 *(u32 *)addr = insn;
40 size = sizeof(u32);
41 }
42
43 flush_icache_range((uintptr_t)(addr),
44 (uintptr_t)(addr) + size);
45}
46
47static int __kprobes patch_text_stop_machine(void *data)
48{
49 struct patch *patch = data;
50
51 __patch_text(patch->addr, patch->insn);
52
53 return 0;
54}
55
56void __kprobes patch_text(void *addr, unsigned int insn)
57{
58 struct patch patch = {
59 .addr = addr,
60 .insn = insn,
61 };
62
63 if (cache_ops_need_broadcast()) {
64 stop_machine(patch_text_stop_machine, &patch, cpu_online_mask);
65 } else {
66 bool straddles_word = IS_ENABLED(CONFIG_THUMB2_KERNEL)
67 && __opcode_is_thumb32(insn)
68 && ((uintptr_t)addr & 2);
69
70 if (straddles_word)
71 stop_machine(patch_text_stop_machine, &patch, NULL);
72 else
73 __patch_text(addr, insn);
74 }
75}
diff --git a/arch/arm/kernel/patch.h b/arch/arm/kernel/patch.h
new file mode 100644
index 00000000000..b4731f2dac3
--- /dev/null
+++ b/arch/arm/kernel/patch.h
@@ -0,0 +1,7 @@
1#ifndef _ARM_KERNEL_PATCH_H
2#define _ARM_KERNEL_PATCH_H
3
4void patch_text(void *addr, unsigned int insn);
5void __patch_text(void *addr, unsigned int insn);
6
7#endif
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 8a89d3b7626..186c8cb982c 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -738,6 +738,9 @@ init_hw_perf_events(void)
738 case 0xC0F0: /* Cortex-A15 */ 738 case 0xC0F0: /* Cortex-A15 */
739 cpu_pmu = armv7_a15_pmu_init(); 739 cpu_pmu = armv7_a15_pmu_init();
740 break; 740 break;
741 case 0xC070: /* Cortex-A7 */
742 cpu_pmu = armv7_a7_pmu_init();
743 break;
741 } 744 }
742 /* Intel CPUs [xscale]. */ 745 /* Intel CPUs [xscale]. */
743 } else if (0x69 == implementor) { 746 } else if (0x69 == implementor) {
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 4d7095af2ab..00755d82e2f 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -610,6 +610,130 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
610}; 610};
611 611
612/* 612/*
613 * Cortex-A7 HW events mapping
614 */
615static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
616 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
617 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
618 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
619 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
620 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
621 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
622 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
623 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
624 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
625};
626
627static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
628 [PERF_COUNT_HW_CACHE_OP_MAX]
629 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
630 [C(L1D)] = {
631 /*
632 * The performance counters don't differentiate between read
633 * and write accesses/misses so this isn't strictly correct,
634 * but it's the best we can do. Writes and reads get
635 * combined.
636 */
637 [C(OP_READ)] = {
638 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
639 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
640 },
641 [C(OP_WRITE)] = {
642 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
643 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
644 },
645 [C(OP_PREFETCH)] = {
646 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
647 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
648 },
649 },
650 [C(L1I)] = {
651 [C(OP_READ)] = {
652 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
653 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
654 },
655 [C(OP_WRITE)] = {
656 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
657 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
658 },
659 [C(OP_PREFETCH)] = {
660 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
661 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
662 },
663 },
664 [C(LL)] = {
665 [C(OP_READ)] = {
666 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
667 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
668 },
669 [C(OP_WRITE)] = {
670 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
671 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
672 },
673 [C(OP_PREFETCH)] = {
674 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
675 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
676 },
677 },
678 [C(DTLB)] = {
679 [C(OP_READ)] = {
680 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
681 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
682 },
683 [C(OP_WRITE)] = {
684 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
685 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
686 },
687 [C(OP_PREFETCH)] = {
688 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
689 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
690 },
691 },
692 [C(ITLB)] = {
693 [C(OP_READ)] = {
694 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
695 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
696 },
697 [C(OP_WRITE)] = {
698 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
699 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
700 },
701 [C(OP_PREFETCH)] = {
702 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
703 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
704 },
705 },
706 [C(BPU)] = {
707 [C(OP_READ)] = {
708 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
709 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
710 },
711 [C(OP_WRITE)] = {
712 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
713 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
714 },
715 [C(OP_PREFETCH)] = {
716 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
717 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
718 },
719 },
720 [C(NODE)] = {
721 [C(OP_READ)] = {
722 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
723 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
724 },
725 [C(OP_WRITE)] = {
726 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
727 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
728 },
729 [C(OP_PREFETCH)] = {
730 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
731 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
732 },
733 },
734};
735
736/*
613 * Perf Events' indices 737 * Perf Events' indices
614 */ 738 */
615#define ARMV7_IDX_CYCLE_COUNTER 0 739#define ARMV7_IDX_CYCLE_COUNTER 0
@@ -1104,6 +1228,12 @@ static int armv7_a15_map_event(struct perf_event *event)
1104 &armv7_a15_perf_cache_map, 0xFF); 1228 &armv7_a15_perf_cache_map, 0xFF);
1105} 1229}
1106 1230
1231static int armv7_a7_map_event(struct perf_event *event)
1232{
1233 return map_cpu_event(event, &armv7_a7_perf_map,
1234 &armv7_a7_perf_cache_map, 0xFF);
1235}
1236
1107static struct arm_pmu armv7pmu = { 1237static struct arm_pmu armv7pmu = {
1108 .handle_irq = armv7pmu_handle_irq, 1238 .handle_irq = armv7pmu_handle_irq,
1109 .enable = armv7pmu_enable_event, 1239 .enable = armv7pmu_enable_event,
@@ -1164,6 +1294,16 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
1164 armv7pmu.set_event_filter = armv7pmu_set_event_filter; 1294 armv7pmu.set_event_filter = armv7pmu_set_event_filter;
1165 return &armv7pmu; 1295 return &armv7pmu;
1166} 1296}
1297
1298static struct arm_pmu *__init armv7_a7_pmu_init(void)
1299{
1300 armv7pmu.id = ARM_PERF_PMU_ID_CA7;
1301 armv7pmu.name = "ARMv7 Cortex-A7";
1302 armv7pmu.map_event = armv7_a7_map_event;
1303 armv7pmu.num_events = armv7_read_num_pmnc_events();
1304 armv7pmu.set_event_filter = armv7pmu_set_event_filter;
1305 return &armv7pmu;
1306}
1167#else 1307#else
1168static struct arm_pmu *__init armv7_a8_pmu_init(void) 1308static struct arm_pmu *__init armv7_a8_pmu_init(void)
1169{ 1309{
@@ -1184,4 +1324,9 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
1184{ 1324{
1185 return NULL; 1325 return NULL;
1186} 1326}
1327
1328static struct arm_pmu *__init armv7_a7_pmu_init(void)
1329{
1330 return NULL;
1331}
1187#endif /* CONFIG_CPU_V7 */ 1332#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 7b9cddef6e5..2b7b017a20c 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -528,21 +528,39 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
528#ifdef CONFIG_MMU 528#ifdef CONFIG_MMU
529/* 529/*
530 * The vectors page is always readable from user space for the 530 * The vectors page is always readable from user space for the
531 * atomic helpers and the signal restart code. Let's declare a mapping 531 * atomic helpers and the signal restart code. Insert it into the
532 * for it so it is visible through ptrace and /proc/<pid>/mem. 532 * gate_vma so that it is visible through ptrace and /proc/<pid>/mem.
533 */ 533 */
534static struct vm_area_struct gate_vma;
534 535
535int vectors_user_mapping(void) 536static int __init gate_vma_init(void)
536{ 537{
537 struct mm_struct *mm = current->mm; 538 gate_vma.vm_start = 0xffff0000;
538 return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, 539 gate_vma.vm_end = 0xffff0000 + PAGE_SIZE;
539 VM_READ | VM_EXEC | 540 gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
540 VM_MAYREAD | VM_MAYEXEC | VM_RESERVED, 541 gate_vma.vm_flags = VM_READ | VM_EXEC |
541 NULL); 542 VM_MAYREAD | VM_MAYEXEC;
543 return 0;
544}
545arch_initcall(gate_vma_init);
546
547struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
548{
549 return &gate_vma;
550}
551
552int in_gate_area(struct mm_struct *mm, unsigned long addr)
553{
554 return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end);
555}
556
557int in_gate_area_no_mm(unsigned long addr)
558{
559 return in_gate_area(NULL, addr);
542} 560}
543 561
544const char *arch_vma_name(struct vm_area_struct *vma) 562const char *arch_vma_name(struct vm_area_struct *vma)
545{ 563{
546 return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL; 564 return (vma == &gate_vma) ? "[vectors]" : NULL;
547} 565}
548#endif 566#endif
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index 5416c7c1252..27d186abbc0 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -10,6 +10,7 @@
10#include <linux/jiffies.h> 10#include <linux/jiffies.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include <linux/syscore_ops.h>
13#include <linux/timer.h> 14#include <linux/timer.h>
14 15
15#include <asm/sched_clock.h> 16#include <asm/sched_clock.h>
@@ -164,3 +165,20 @@ void __init sched_clock_postinit(void)
164 165
165 sched_clock_poll(sched_clock_timer.data); 166 sched_clock_poll(sched_clock_timer.data);
166} 167}
168
169static int sched_clock_suspend(void)
170{
171 sched_clock_poll(sched_clock_timer.data);
172 return 0;
173}
174
175static struct syscore_ops sched_clock_ops = {
176 .suspend = sched_clock_suspend,
177};
178
179static int __init sched_clock_syscore_init(void)
180{
181 register_syscore_ops(&sched_clock_ops);
182 return 0;
183}
184device_initcall(sched_clock_syscore_init);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 9e0fdb3a198..b91411371ae 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -976,7 +976,6 @@ void __init setup_arch(char **cmdline_p)
976 conswitchp = &dummy_con; 976 conswitchp = &dummy_con;
977#endif 977#endif
978#endif 978#endif
979 early_trap_init();
980 979
981 if (mdesc->init_early) 980 if (mdesc->init_early)
982 mdesc->init_early(); 981 mdesc->init_early();
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 9e617bd4a14..7cb532fc8aa 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -66,12 +66,13 @@ const unsigned long syscall_restart_code[2] = {
66 */ 66 */
67asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) 67asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
68{ 68{
69 mask &= _BLOCKABLE; 69 sigset_t blocked;
70 spin_lock_irq(&current->sighand->siglock); 70
71 current->saved_sigmask = current->blocked; 71 current->saved_sigmask = current->blocked;
72 siginitset(&current->blocked, mask); 72
73 recalc_sigpending(); 73 mask &= _BLOCKABLE;
74 spin_unlock_irq(&current->sighand->siglock); 74 siginitset(&blocked, mask);
75 set_current_blocked(&blocked);
75 76
76 current->state = TASK_INTERRUPTIBLE; 77 current->state = TASK_INTERRUPTIBLE;
77 schedule(); 78 schedule();
@@ -280,10 +281,7 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
280 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); 281 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
281 if (err == 0) { 282 if (err == 0) {
282 sigdelsetmask(&set, ~_BLOCKABLE); 283 sigdelsetmask(&set, ~_BLOCKABLE);
283 spin_lock_irq(&current->sighand->siglock); 284 set_current_blocked(&set);
284 current->blocked = set;
285 recalc_sigpending();
286 spin_unlock_irq(&current->sighand->siglock);
287 } 285 }
288 286
289 __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); 287 __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
@@ -636,13 +634,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
636 /* 634 /*
637 * Block the signal if we were successful. 635 * Block the signal if we were successful.
638 */ 636 */
639 spin_lock_irq(&tsk->sighand->siglock); 637 block_sigmask(ka, sig);
640 sigorsets(&tsk->blocked, &tsk->blocked,
641 &ka->sa.sa_mask);
642 if (!(ka->sa.sa_flags & SA_NODEFER))
643 sigaddset(&tsk->blocked, sig);
644 recalc_sigpending();
645 spin_unlock_irq(&tsk->sighand->siglock);
646 638
647 return 0; 639 return 0;
648} 640}
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8f8cce2c46c..2cee7d1eb95 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -58,6 +58,8 @@ enum ipi_msg_type {
58 IPI_CPU_STOP, 58 IPI_CPU_STOP,
59}; 59};
60 60
61static DECLARE_COMPLETION(cpu_running);
62
61int __cpuinit __cpu_up(unsigned int cpu) 63int __cpuinit __cpu_up(unsigned int cpu)
62{ 64{
63 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); 65 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
@@ -98,20 +100,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
98 */ 100 */
99 ret = boot_secondary(cpu, idle); 101 ret = boot_secondary(cpu, idle);
100 if (ret == 0) { 102 if (ret == 0) {
101 unsigned long timeout;
102
103 /* 103 /*
104 * CPU was successfully started, wait for it 104 * CPU was successfully started, wait for it
105 * to come online or time out. 105 * to come online or time out.
106 */ 106 */
107 timeout = jiffies + HZ; 107 wait_for_completion_timeout(&cpu_running,
108 while (time_before(jiffies, timeout)) { 108 msecs_to_jiffies(1000));
109 if (cpu_online(cpu))
110 break;
111
112 udelay(10);
113 barrier();
114 }
115 109
116 if (!cpu_online(cpu)) { 110 if (!cpu_online(cpu)) {
117 pr_crit("CPU%u: failed to come online\n", cpu); 111 pr_crit("CPU%u: failed to come online\n", cpu);
@@ -288,9 +282,10 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
288 /* 282 /*
289 * OK, now it's safe to let the boot CPU continue. Wait for 283 * OK, now it's safe to let the boot CPU continue. Wait for
290 * the CPU migration code to notice that the CPU is online 284 * the CPU migration code to notice that the CPU is online
291 * before we continue. 285 * before we continue - which happens after __cpu_up returns.
292 */ 286 */
293 set_cpu_online(cpu, true); 287 set_cpu_online(cpu, true);
288 complete(&cpu_running);
294 289
295 /* 290 /*
296 * Setup the percpu timer for this CPU. 291 * Setup the percpu timer for this CPU.
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 8c57dd3680e..fe31b22f18f 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -25,8 +25,6 @@
25#include <linux/timer.h> 25#include <linux/timer.h>
26#include <linux/irq.h> 26#include <linux/irq.h>
27 27
28#include <linux/mc146818rtc.h>
29
30#include <asm/leds.h> 28#include <asm/leds.h>
31#include <asm/thread_info.h> 29#include <asm/thread_info.h>
32#include <asm/sched_clock.h> 30#include <asm/sched_clock.h>
@@ -149,8 +147,6 @@ void __init time_init(void)
149{ 147{
150 system_timer = machine_desc->timer; 148 system_timer = machine_desc->timer;
151 system_timer->init(); 149 system_timer->init();
152#ifdef CONFIG_HAVE_SCHED_CLOCK
153 sched_clock_postinit(); 150 sched_clock_postinit();
154#endif
155} 151}
156 152
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index cd77743472a..778454750a6 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -227,6 +227,11 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
227#else 227#else
228#define S_SMP "" 228#define S_SMP ""
229#endif 229#endif
230#ifdef CONFIG_THUMB2_KERNEL
231#define S_ISA " THUMB2"
232#else
233#define S_ISA " ARM"
234#endif
230 235
231static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) 236static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
232{ 237{
@@ -234,8 +239,8 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
234 static int die_counter; 239 static int die_counter;
235 int ret; 240 int ret;
236 241
237 printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", 242 printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP
238 str, err, ++die_counter); 243 S_ISA "\n", str, err, ++die_counter);
239 244
240 /* trap and error numbers are mostly meaningless on ARM */ 245 /* trap and error numbers are mostly meaningless on ARM */
241 ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); 246 ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
@@ -784,18 +789,16 @@ static void __init kuser_get_tls_init(unsigned long vectors)
784 memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); 789 memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
785} 790}
786 791
787void __init early_trap_init(void) 792void __init early_trap_init(void *vectors_base)
788{ 793{
789#if defined(CONFIG_CPU_USE_DOMAINS) 794 unsigned long vectors = (unsigned long)vectors_base;
790 unsigned long vectors = CONFIG_VECTORS_BASE;
791#else
792 unsigned long vectors = (unsigned long)vectors_page;
793#endif
794 extern char __stubs_start[], __stubs_end[]; 795 extern char __stubs_start[], __stubs_end[];
795 extern char __vectors_start[], __vectors_end[]; 796 extern char __vectors_start[], __vectors_end[];
796 extern char __kuser_helper_start[], __kuser_helper_end[]; 797 extern char __kuser_helper_start[], __kuser_helper_end[];
797 int kuser_sz = __kuser_helper_end - __kuser_helper_start; 798 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
798 799
800 vectors_page = vectors_base;
801
799 /* 802 /*
800 * Copy the vectors, stubs and kuser helpers (in entry-armv.S) 803 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
801 * into the vector page, mapped at 0xffff0000, and ensure these 804 * into the vector page, mapped at 0xffff0000, and ensure these
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index e1969ce904d..75da315b658 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -19,11 +19,14 @@
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21 21
22#include <mach/hardware.h> 22#include <asm/sched_clock.h>
23#include <asm/mach/irq.h> 23#include <asm/mach/irq.h>
24#include <asm/mach/time.h> 24#include <asm/mach/time.h>
25
25#include <mach/cputype.h> 26#include <mach/cputype.h>
27#include <mach/hardware.h>
26#include <mach/time.h> 28#include <mach/time.h>
29
27#include "clock.h" 30#include "clock.h"
28 31
29static struct clock_event_device clockevent_davinci; 32static struct clock_event_device clockevent_davinci;
@@ -272,19 +275,9 @@ static cycle_t read_cycles(struct clocksource *cs)
272 return (cycles_t)timer32_read(t); 275 return (cycles_t)timer32_read(t);
273} 276}
274 277
275/*
276 * Kernel assumes that sched_clock can be called early but may not have
277 * things ready yet.
278 */
279static cycle_t read_dummy(struct clocksource *cs)
280{
281 return 0;
282}
283
284
285static struct clocksource clocksource_davinci = { 278static struct clocksource clocksource_davinci = {
286 .rating = 300, 279 .rating = 300,
287 .read = read_dummy, 280 .read = read_cycles,
288 .mask = CLOCKSOURCE_MASK(32), 281 .mask = CLOCKSOURCE_MASK(32),
289 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 282 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
290}; 283};
@@ -292,12 +285,9 @@ static struct clocksource clocksource_davinci = {
292/* 285/*
293 * Overwrite weak default sched_clock with something more precise 286 * Overwrite weak default sched_clock with something more precise
294 */ 287 */
295unsigned long long notrace sched_clock(void) 288static u32 notrace davinci_read_sched_clock(void)
296{ 289{
297 const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); 290 return timer32_read(&timers[TID_CLOCKSOURCE]);
298
299 return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
300 clocksource_davinci.shift);
301} 291}
302 292
303/* 293/*
@@ -397,12 +387,14 @@ static void __init davinci_timer_init(void)
397 davinci_clock_tick_rate = clk_get_rate(timer_clk); 387 davinci_clock_tick_rate = clk_get_rate(timer_clk);
398 388
399 /* setup clocksource */ 389 /* setup clocksource */
400 clocksource_davinci.read = read_cycles;
401 clocksource_davinci.name = id_to_name[clocksource_id]; 390 clocksource_davinci.name = id_to_name[clocksource_id];
402 if (clocksource_register_hz(&clocksource_davinci, 391 if (clocksource_register_hz(&clocksource_davinci,
403 davinci_clock_tick_rate)) 392 davinci_clock_tick_rate))
404 printk(err, clocksource_davinci.name); 393 printk(err, clocksource_davinci.name);
405 394
395 setup_sched_clock(davinci_read_sched_clock, 32,
396 davinci_clock_tick_rate);
397
406 /* setup clockevent */ 398 /* setup clockevent */
407 clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; 399 clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
408 clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, 400 clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 808b055289b..410a112bb52 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -35,7 +35,6 @@
35#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
36#include <asm/mach/map.h> 36#include <asm/mach/map.h>
37#include <asm/mach/time.h> 37#include <asm/mach/time.h>
38#include <mach/irqs.h>
39 38
40#include "core.h" 39#include "core.h"
41#include "sysregs.h" 40#include "sysregs.h"
diff --git a/arch/arm/mach-highbank/include/mach/irqs.h b/arch/arm/mach-highbank/include/mach/irqs.h
deleted file mode 100644
index 9746aab14e9..00000000000
--- a/arch/arm/mach-highbank/include/mach/irqs.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __MACH_IRQS_H
2#define __MACH_IRQS_H
3
4#define NR_IRQS 192
5
6#endif
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 1a65d77bd55..eaf6c6366ff 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -25,8 +25,9 @@
25 25
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/platform.h> 27#include <mach/platform.h>
28#include <asm/irq.h>
29#include <mach/cm.h> 28#include <mach/cm.h>
29#include <mach/irqs.h>
30
30#include <asm/leds.h> 31#include <asm/leds.h>
31#include <asm/mach-types.h> 32#include <asm/mach-types.h>
32#include <asm/mach/time.h> 33#include <asm/mach/time.h>
diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h
index 1fbe6d19022..a19a1a2fcf6 100644
--- a/arch/arm/mach-integrator/include/mach/irqs.h
+++ b/arch/arm/mach-integrator/include/mach/irqs.h
@@ -78,5 +78,6 @@
78#define IRQ_SIC_CP_LMINT7 46 78#define IRQ_SIC_CP_LMINT7 46
79#define IRQ_SIC_END 46 79#define IRQ_SIC_END 46
80 80
81#define NR_IRQS 47 81#define NR_IRQS_INTEGRATOR_AP 34
82#define NR_IRQS_INTEGRATOR_CP 47
82 83
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 21a1d6cbef4..871f148ffd7 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -38,12 +38,13 @@
38#include <mach/hardware.h> 38#include <mach/hardware.h>
39#include <mach/platform.h> 39#include <mach/platform.h>
40#include <asm/hardware/arm_timer.h> 40#include <asm/hardware/arm_timer.h>
41#include <asm/irq.h>
42#include <asm/setup.h> 41#include <asm/setup.h>
43#include <asm/param.h> /* HZ */ 42#include <asm/param.h> /* HZ */
44#include <asm/mach-types.h> 43#include <asm/mach-types.h>
44#include <asm/sched_clock.h>
45 45
46#include <mach/lm.h> 46#include <mach/lm.h>
47#include <mach/irqs.h>
47 48
48#include <asm/mach/arch.h> 49#include <asm/mach/arch.h>
49#include <asm/mach/irq.h> 50#include <asm/mach/irq.h>
@@ -325,6 +326,11 @@ static void __init ap_init(void)
325 326
326static unsigned long timer_reload; 327static unsigned long timer_reload;
327 328
329static u32 notrace integrator_read_sched_clock(void)
330{
331 return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
332}
333
328static void integrator_clocksource_init(unsigned long inrate) 334static void integrator_clocksource_init(unsigned long inrate)
329{ 335{
330 void __iomem *base = (void __iomem *)TIMER2_VA_BASE; 336 void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
@@ -341,6 +347,7 @@ static void integrator_clocksource_init(unsigned long inrate)
341 347
342 clocksource_mmio_init(base + TIMER_VALUE, "timer2", 348 clocksource_mmio_init(base + TIMER_VALUE, "timer2",
343 rate, 200, 16, clocksource_mmio_readl_down); 349 rate, 200, 16, clocksource_mmio_readl_down);
350 setup_sched_clock(integrator_read_sched_clock, 16, rate);
344} 351}
345 352
346static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; 353static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
@@ -468,6 +475,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
468 .atag_offset = 0x100, 475 .atag_offset = 0x100,
469 .reserve = integrator_reserve, 476 .reserve = integrator_reserve,
470 .map_io = ap_map_io, 477 .map_io = ap_map_io,
478 .nr_irqs = NR_IRQS_INTEGRATOR_AP,
471 .init_early = integrator_init_early, 479 .init_early = integrator_init_early,
472 .init_irq = ap_init_irq, 480 .init_irq = ap_init_irq,
473 .timer = &ap_timer, 481 .timer = &ap_timer,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index be9ead4a3bc..48a115a91d9 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -26,7 +26,6 @@
26 26
27#include <mach/hardware.h> 27#include <mach/hardware.h>
28#include <mach/platform.h> 28#include <mach/platform.h>
29#include <asm/irq.h>
30#include <asm/setup.h> 29#include <asm/setup.h>
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <asm/hardware/arm_timer.h> 31#include <asm/hardware/arm_timer.h>
@@ -34,6 +33,7 @@
34 33
35#include <mach/cm.h> 34#include <mach/cm.h>
36#include <mach/lm.h> 35#include <mach/lm.h>
36#include <mach/irqs.h>
37 37
38#include <asm/mach/arch.h> 38#include <asm/mach/arch.h>
39#include <asm/mach/irq.h> 39#include <asm/mach/irq.h>
@@ -464,6 +464,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
464 .atag_offset = 0x100, 464 .atag_offset = 0x100,
465 .reserve = integrator_reserve, 465 .reserve = integrator_reserve,
466 .map_io = intcp_map_io, 466 .map_io = intcp_map_io,
467 .nr_irqs = NR_IRQS_INTEGRATOR_CP,
467 .init_early = intcp_init_early, 468 .init_early = intcp_init_early,
468 .init_irq = intcp_init_irq, 469 .init_irq = intcp_init_irq,
469 .timer = &cp_timer, 470 .timer = &cp_timer,
diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
index 36068f438f2..f1ca9c12286 100644
--- a/arch/arm/mach-integrator/pci.c
+++ b/arch/arm/mach-integrator/pci.c
@@ -26,10 +26,11 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/init.h> 27#include <linux/init.h>
28 28
29#include <asm/irq.h>
30#include <asm/mach/pci.h> 29#include <asm/mach/pci.h>
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32 31
32#include <mach/irqs.h>
33
33/* 34/*
34 * A small note about bridges and interrupts. The DECchip 21050 (and 35 * A small note about bridges and interrupts. The DECchip 21050 (and
35 * later) adheres to the PCI-PCI bridge specification. This says that 36 * later) adheres to the PCI-PCI bridge specification. This says that
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 4be172c3cbe..67e6f9a9d1a 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -30,7 +30,8 @@
30 30
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <mach/platform.h> 32#include <mach/platform.h>
33#include <asm/irq.h> 33#include <mach/irqs.h>
34
34#include <asm/signal.h> 35#include <asm/signal.h>
35#include <asm/mach/pci.h> 36#include <asm/mach/pci.h>
36#include <asm/irq_regs.h> 37#include <asm/irq_regs.h>
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 3588a558415..bf5d8e195c3 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -23,6 +23,7 @@
23#include <mach/addr-map.h> 23#include <mach/addr-map.h>
24#include <mach/mfp-pxa168.h> 24#include <mach/mfp-pxa168.h>
25#include <mach/pxa168.h> 25#include <mach/pxa168.h>
26#include <mach/irqs.h>
26#include <video/pxa168fb.h> 27#include <video/pxa168fb.h>
27#include <linux/input.h> 28#include <linux/input.h>
28#include <plat/pxa27x_keypad.h> 29#include <plat/pxa27x_keypad.h>
@@ -239,7 +240,7 @@ static void __init common_init(void)
239 240
240MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform") 241MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
241 .map_io = mmp_map_io, 242 .map_io = mmp_map_io,
242 .nr_irqs = IRQ_BOARD_START, 243 .nr_irqs = MMP_NR_IRQS,
243 .init_irq = pxa168_init_irq, 244 .init_irq = pxa168_init_irq,
244 .timer = &pxa168_timer, 245 .timer = &pxa168_timer,
245 .init_machine = common_init, 246 .init_machine = common_init,
@@ -248,7 +249,7 @@ MACHINE_END
248 249
249MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform") 250MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
250 .map_io = mmp_map_io, 251 .map_io = mmp_map_io,
251 .nr_irqs = IRQ_BOARD_START, 252 .nr_irqs = MMP_NR_IRQS,
252 .init_irq = pxa168_init_irq, 253 .init_irq = pxa168_init_irq,
253 .timer = &pxa168_timer, 254 .timer = &pxa168_timer,
254 .init_machine = common_init, 255 .init_machine = common_init,
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index b148a9dc5a4..603542ae6fb 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -43,6 +43,7 @@ static void __init avengers_lite_init(void)
43 43
44MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform") 44MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
45 .map_io = mmp_map_io, 45 .map_io = mmp_map_io,
46 .nr_irqs = MMP_NR_IRQS,
46 .init_irq = pxa168_init_irq, 47 .init_irq = pxa168_init_irq,
47 .timer = &pxa168_timer, 48 .timer = &pxa168_timer,
48 .init_machine = avengers_lite_init, 49 .init_machine = avengers_lite_init,
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index d839fe6421e..5cb769cd26d 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -28,7 +28,7 @@
28 28
29#include "common.h" 29#include "common.h"
30 30
31#define BROWNSTONE_NR_IRQS (IRQ_BOARD_START + 40) 31#define BROWNSTONE_NR_IRQS (MMP_NR_IRQS + 40)
32 32
33#define GPIO_5V_ENABLE (89) 33#define GPIO_5V_ENABLE (89)
34 34
@@ -158,7 +158,7 @@ static struct platform_device brownstone_v_5vp_device = {
158}; 158};
159 159
160static struct max8925_platform_data brownstone_max8925_info = { 160static struct max8925_platform_data brownstone_max8925_info = {
161 .irq_base = IRQ_BOARD_START, 161 .irq_base = MMP_NR_IRQS,
162}; 162};
163 163
164static struct i2c_board_info brownstone_twsi1_info[] = { 164static struct i2c_board_info brownstone_twsi1_info[] = {
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 2ee8cd7829d..8059cc0905c 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -23,10 +23,11 @@
23#include <mach/addr-map.h> 23#include <mach/addr-map.h>
24#include <mach/mfp-mmp2.h> 24#include <mach/mfp-mmp2.h>
25#include <mach/mmp2.h> 25#include <mach/mmp2.h>
26#include <mach/irqs.h>
26 27
27#include "common.h" 28#include "common.h"
28 29
29#define FLINT_NR_IRQS (IRQ_BOARD_START + 48) 30#define FLINT_NR_IRQS (MMP_NR_IRQS + 48)
30 31
31static unsigned long flint_pin_config[] __initdata = { 32static unsigned long flint_pin_config[] __initdata = {
32 /* UART1 */ 33 /* UART1 */
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 87765467de6..f516e74ce0d 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -191,7 +191,7 @@ static void __init gplugd_init(void)
191 191
192MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform") 192MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
193 .map_io = mmp_map_io, 193 .map_io = mmp_map_io,
194 .nr_irqs = IRQ_BOARD_START, 194 .nr_irqs = MMP_NR_IRQS,
195 .init_irq = pxa168_init_irq, 195 .init_irq = pxa168_init_irq,
196 .timer = &pxa168_timer, 196 .timer = &pxa168_timer,
197 .init_machine = gplugd_init, 197 .init_machine = gplugd_init,
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index 34635a0bbb5..d0e746626a3 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -223,7 +223,6 @@
223#define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio)) 223#define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio))
224 224
225#define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO) 225#define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO)
226 226#define MMP_NR_IRQS IRQ_BOARD_START
227#define NR_IRQS (IRQ_BOARD_START)
228 227
229#endif /* __ASM_MACH_IRQS_H */ 228#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c
index d21c5441a3d..7895d277421 100644
--- a/arch/arm/mach-mmp/irq-mmp2.c
+++ b/arch/arm/mach-mmp/irq-mmp2.c
@@ -15,6 +15,7 @@
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/io.h> 16#include <linux/io.h>
17 17
18#include <mach/irqs.h>
18#include <mach/regs-icu.h> 19#include <mach/regs-icu.h>
19#include <mach/mmp2.h> 20#include <mach/mmp2.h>
20 21
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
index 96cf5c8fe47..ff73249884d 100644
--- a/arch/arm/mach-mmp/jasper.c
+++ b/arch/arm/mach-mmp/jasper.c
@@ -19,6 +19,7 @@
19#include <linux/mfd/max8925.h> 19#include <linux/mfd/max8925.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21 21
22#include <mach/irqs.h>
22#include <asm/mach-types.h> 23#include <asm/mach-types.h>
23#include <asm/mach/arch.h> 24#include <asm/mach/arch.h>
24#include <mach/addr-map.h> 25#include <mach/addr-map.h>
@@ -27,7 +28,7 @@
27 28
28#include "common.h" 29#include "common.h"
29 30
30#define JASPER_NR_IRQS (IRQ_BOARD_START + 48) 31#define JASPER_NR_IRQS (MMP_NR_IRQS + 48)
31 32
32static unsigned long jasper_pin_config[] __initdata = { 33static unsigned long jasper_pin_config[] __initdata = {
33 /* UART1 */ 34 /* UART1 */
@@ -135,7 +136,7 @@ static struct max8925_power_pdata jasper_power_data = {
135static struct max8925_platform_data jasper_max8925_info = { 136static struct max8925_platform_data jasper_max8925_info = {
136 .backlight = &jasper_backlight_data, 137 .backlight = &jasper_backlight_data,
137 .power = &jasper_power_data, 138 .power = &jasper_power_data,
138 .irq_base = IRQ_BOARD_START, 139 .irq_base = MMP_NR_IRQS,
139}; 140};
140 141
141static struct i2c_board_info jasper_twsi1_info[] = { 142static struct i2c_board_info jasper_twsi1_info[] = {
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index bc97170125b..b28f9084dff 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -101,6 +101,7 @@ static void __init tavorevb_init(void)
101 101
102MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)") 102MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
103 .map_io = mmp_map_io, 103 .map_io = mmp_map_io,
104 .nr_irqs = MMP_NR_IRQS,
104 .init_irq = pxa910_init_irq, 105 .init_irq = pxa910_init_irq,
105 .timer = &pxa910_timer, 106 .timer = &pxa910_timer,
106 .init_machine = tavorevb_init, 107 .init_machine = tavorevb_init,
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 0523e422990..42bef6674ec 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -26,6 +26,7 @@
26#include <mach/mfp-pxa168.h> 26#include <mach/mfp-pxa168.h>
27#include <mach/pxa168.h> 27#include <mach/pxa168.h>
28#include <mach/teton_bga.h> 28#include <mach/teton_bga.h>
29#include <mach/irqs.h>
29 30
30#include "common.h" 31#include "common.h"
31 32
@@ -83,7 +84,7 @@ static void __init teton_bga_init(void)
83 84
84MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform") 85MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
85 .map_io = mmp_map_io, 86 .map_io = mmp_map_io,
86 .nr_irqs = IRQ_BOARD_START, 87 .nr_irqs = MMP_NR_IRQS,
87 .init_irq = pxa168_init_irq, 88 .init_irq = pxa168_init_irq,
88 .timer = &pxa168_timer, 89 .timer = &pxa168_timer,
89 .init_machine = teton_bga_init, 90 .init_machine = teton_bga_init,
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index e72c709da44..3fc9ed21f97 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -38,7 +38,7 @@
38 * 16 board interrupts -- PCA9575 GPIO expander 38 * 16 board interrupts -- PCA9575 GPIO expander
39 * 24 board interrupts -- 88PM860x PMIC 39 * 24 board interrupts -- 88PM860x PMIC
40 */ 40 */
41#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 16 + 16 + 24) 41#define TTCDKB_NR_IRQS (MMP_NR_IRQS + 16 + 16 + 24)
42 42
43static unsigned long ttc_dkb_pin_config[] __initdata = { 43static unsigned long ttc_dkb_pin_config[] __initdata = {
44 /* UART2 */ 44 /* UART2 */
@@ -131,7 +131,7 @@ static struct platform_device *ttc_dkb_devices[] = {
131static struct pca953x_platform_data max7312_data[] = { 131static struct pca953x_platform_data max7312_data[] = {
132 { 132 {
133 .gpio_base = TTCDKB_GPIO_EXT0(0), 133 .gpio_base = TTCDKB_GPIO_EXT0(0),
134 .irq_base = IRQ_BOARD_START, 134 .irq_base = MMP_NR_IRQS,
135 }, 135 },
136}; 136};
137 137
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 75f4be40b3e..81280825493 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -24,6 +24,7 @@
24#include <asm/mach/time.h> 24#include <asm/mach/time.h>
25#include <asm/hardware/gic.h> 25#include <asm/hardware/gic.h>
26#include <asm/localtimer.h> 26#include <asm/localtimer.h>
27#include <asm/sched_clock.h>
27 28
28#include <mach/msm_iomap.h> 29#include <mach/msm_iomap.h>
29#include <mach/cpu.h> 30#include <mach/cpu.h>
@@ -105,12 +106,12 @@ static union {
105 106
106static void __iomem *source_base; 107static void __iomem *source_base;
107 108
108static cycle_t msm_read_timer_count(struct clocksource *cs) 109static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
109{ 110{
110 return readl_relaxed(source_base + TIMER_COUNT_VAL); 111 return readl_relaxed(source_base + TIMER_COUNT_VAL);
111} 112}
112 113
113static cycle_t msm_read_timer_count_shift(struct clocksource *cs) 114static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
114{ 115{
115 /* 116 /*
116 * Shift timer count down by a constant due to unreliable lower bits 117 * Shift timer count down by a constant due to unreliable lower bits
@@ -166,6 +167,11 @@ static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
166}; 167};
167#endif /* CONFIG_LOCAL_TIMERS */ 168#endif /* CONFIG_LOCAL_TIMERS */
168 169
170static notrace u32 msm_sched_clock_read(void)
171{
172 return msm_clocksource.read(&msm_clocksource);
173}
174
169static void __init msm_timer_init(void) 175static void __init msm_timer_init(void)
170{ 176{
171 struct clock_event_device *ce = &msm_clockevent; 177 struct clock_event_device *ce = &msm_clockevent;
@@ -232,6 +238,8 @@ err:
232 res = clocksource_register_hz(cs, dgt_hz); 238 res = clocksource_register_hz(cs, dgt_hz);
233 if (res) 239 if (res)
234 pr_err("clocksource_register failed\n"); 240 pr_err("clocksource_register failed\n");
241 setup_sched_clock(msm_sched_clock_read,
242 cpu_is_msm7x01() ? 32 - MSM_DGT_SHIFT : 32, dgt_hz);
235} 243}
236 244
237struct sys_timer msm_timer = { 245struct sys_timer msm_timer = {
diff --git a/arch/arm/mach-picoxcell/include/mach/irqs.h b/arch/arm/mach-picoxcell/include/mach/irqs.h
deleted file mode 100644
index 59eac1ee282..00000000000
--- a/arch/arm/mach-picoxcell/include/mach/irqs.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef __MACH_IRQS_H
15#define __MACH_IRQS_H
16
17/* We dynamically allocate our irq_desc's. */
18#define NR_IRQS 0
19
20#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index b7a6091ce79..0d024b1e916 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -18,6 +18,7 @@
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/of_address.h> 19#include <linux/of_address.h>
20#include <mach/map.h> 20#include <mach/map.h>
21#include <asm/sched_clock.h>
21#include <asm/mach/time.h> 22#include <asm/mach/time.h>
22 23
23#define SIRFSOC_TIMER_COUNTER_LO 0x0000 24#define SIRFSOC_TIMER_COUNTER_LO 0x0000
@@ -165,21 +166,9 @@ static struct irqaction sirfsoc_timer_irq = {
165}; 166};
166 167
167/* Overwrite weak default sched_clock with more precise one */ 168/* Overwrite weak default sched_clock with more precise one */
168unsigned long long notrace sched_clock(void) 169static u32 notrace sirfsoc_read_sched_clock(void)
169{ 170{
170 static int is_mapped; 171 return (u32)(sirfsoc_timer_read(NULL) & 0xffffffff);
171
172 /*
173 * sched_clock is called earlier than .init of sys_timer
174 * if we map timer memory in .init of sys_timer, system
175 * will panic due to illegal memory access
176 */
177 if (!is_mapped) {
178 sirfsoc_of_timer_map();
179 is_mapped = 1;
180 }
181
182 return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE);
183} 172}
184 173
185static void __init sirfsoc_clockevent_init(void) 174static void __init sirfsoc_clockevent_init(void)
@@ -210,6 +199,8 @@ static void __init sirfsoc_timer_init(void)
210 BUG_ON(rate < CLOCK_TICK_RATE); 199 BUG_ON(rate < CLOCK_TICK_RATE);
211 BUG_ON(rate % CLOCK_TICK_RATE); 200 BUG_ON(rate % CLOCK_TICK_RATE);
212 201
202 sirfsoc_of_timer_map();
203
213 writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); 204 writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
214 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); 205 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
215 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); 206 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
@@ -217,6 +208,8 @@ static void __init sirfsoc_timer_init(void)
217 208
218 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); 209 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
219 210
211 setup_sched_clock(sirfsoc_read_sched_clock, 32, CLOCK_TICK_RATE);
212
220 BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); 213 BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
221 214
222 sirfsoc_clockevent_init(); 215 sirfsoc_clockevent_init();
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
index c91727d1fe0..9a8760b7291 100644
--- a/arch/arm/mach-pxa/capc7117.c
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -150,6 +150,7 @@ MACHINE_START(CAPC7117,
150 "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM") 150 "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
151 .atag_offset = 0x100, 151 .atag_offset = 0x100,
152 .map_io = pxa3xx_map_io, 152 .map_io = pxa3xx_map_io,
153 .nr_irqs = PXA_NR_IRQS,
153 .init_irq = pxa3xx_init_irq, 154 .init_irq = pxa3xx_init_irq,
154 .handle_irq = pxa3xx_handle_irq, 155 .handle_irq = pxa3xx_handle_irq,
155 .timer = &pxa_timer, 156 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 895ee8c4500..638eebedc88 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -854,6 +854,7 @@ static void __init cm_x300_fixup(struct tag *tags, char **cmdline,
854MACHINE_START(CM_X300, "CM-X300 module") 854MACHINE_START(CM_X300, "CM-X300 module")
855 .atag_offset = 0x100, 855 .atag_offset = 0x100,
856 .map_io = pxa3xx_map_io, 856 .map_io = pxa3xx_map_io,
857 .nr_irqs = PXA_NR_IRQS,
857 .init_irq = pxa3xx_init_irq, 858 .init_irq = pxa3xx_init_irq,
858 .handle_irq = pxa3xx_handle_irq, 859 .handle_irq = pxa3xx_handle_irq,
859 .timer = &pxa_timer, 860 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c
index 29d5d541f60..b2f227d3612 100644
--- a/arch/arm/mach-pxa/colibri-pxa270.c
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -310,6 +310,7 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
310 .atag_offset = 0x100, 310 .atag_offset = 0x100,
311 .init_machine = colibri_pxa270_init, 311 .init_machine = colibri_pxa270_init,
312 .map_io = pxa27x_map_io, 312 .map_io = pxa27x_map_io,
313 .nr_irqs = PXA_NR_IRQS,
313 .init_irq = pxa27x_init_irq, 314 .init_irq = pxa27x_init_irq,
314 .handle_irq = pxa27x_handle_irq, 315 .handle_irq = pxa27x_handle_irq,
315 .timer = &pxa_timer, 316 .timer = &pxa_timer,
@@ -320,6 +321,7 @@ MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
320 .atag_offset = 0x100, 321 .atag_offset = 0x100,
321 .init_machine = colibri_pxa270_income_init, 322 .init_machine = colibri_pxa270_income_init,
322 .map_io = pxa27x_map_io, 323 .map_io = pxa27x_map_io,
324 .nr_irqs = PXA_NR_IRQS,
323 .init_irq = pxa27x_init_irq, 325 .init_irq = pxa27x_init_irq,
324 .handle_irq = pxa27x_handle_irq, 326 .handle_irq = pxa27x_handle_irq,
325 .timer = &pxa_timer, 327 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
index 0846d210cb0..bb6def8ec97 100644
--- a/arch/arm/mach-pxa/colibri-pxa300.c
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -186,6 +186,7 @@ MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
186 .atag_offset = 0x100, 186 .atag_offset = 0x100,
187 .init_machine = colibri_pxa300_init, 187 .init_machine = colibri_pxa300_init,
188 .map_io = pxa3xx_map_io, 188 .map_io = pxa3xx_map_io,
189 .nr_irqs = PXA_NR_IRQS,
189 .init_irq = pxa3xx_init_irq, 190 .init_irq = pxa3xx_init_irq,
190 .handle_irq = pxa3xx_handle_irq, 191 .handle_irq = pxa3xx_handle_irq,
191 .timer = &pxa_timer, 192 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index 6ad3359063a..d88e7b37f1d 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -256,6 +256,7 @@ MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
256 .atag_offset = 0x100, 256 .atag_offset = 0x100,
257 .init_machine = colibri_pxa320_init, 257 .init_machine = colibri_pxa320_init,
258 .map_io = pxa3xx_map_io, 258 .map_io = pxa3xx_map_io,
259 .nr_irqs = PXA_NR_IRQS,
259 .init_irq = pxa3xx_init_irq, 260 .init_irq = pxa3xx_init_irq,
260 .handle_irq = pxa3xx_handle_irq, 261 .handle_irq = pxa3xx_handle_irq,
261 .timer = &pxa_timer, 262 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index de9d45e673f..c1fe32db475 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -729,6 +729,7 @@ static void __init fixup_corgi(struct tag *tags, char **cmdline,
729MACHINE_START(CORGI, "SHARP Corgi") 729MACHINE_START(CORGI, "SHARP Corgi")
730 .fixup = fixup_corgi, 730 .fixup = fixup_corgi,
731 .map_io = pxa25x_map_io, 731 .map_io = pxa25x_map_io,
732 .nr_irqs = PXA_NR_IRQS,
732 .init_irq = pxa25x_init_irq, 733 .init_irq = pxa25x_init_irq,
733 .handle_irq = pxa25x_handle_irq, 734 .handle_irq = pxa25x_handle_irq,
734 .init_machine = corgi_init, 735 .init_machine = corgi_init,
@@ -741,6 +742,7 @@ MACHINE_END
741MACHINE_START(SHEPHERD, "SHARP Shepherd") 742MACHINE_START(SHEPHERD, "SHARP Shepherd")
742 .fixup = fixup_corgi, 743 .fixup = fixup_corgi,
743 .map_io = pxa25x_map_io, 744 .map_io = pxa25x_map_io,
745 .nr_irqs = PXA_NR_IRQS,
744 .init_irq = pxa25x_init_irq, 746 .init_irq = pxa25x_init_irq,
745 .handle_irq = pxa25x_handle_irq, 747 .handle_irq = pxa25x_handle_irq,
746 .init_machine = corgi_init, 748 .init_machine = corgi_init,
@@ -753,6 +755,7 @@ MACHINE_END
753MACHINE_START(HUSKY, "SHARP Husky") 755MACHINE_START(HUSKY, "SHARP Husky")
754 .fixup = fixup_corgi, 756 .fixup = fixup_corgi,
755 .map_io = pxa25x_map_io, 757 .map_io = pxa25x_map_io,
758 .nr_irqs = PXA_NR_IRQS,
756 .init_irq = pxa25x_init_irq, 759 .init_irq = pxa25x_init_irq,
757 .handle_irq = pxa25x_handle_irq, 760 .handle_irq = pxa25x_handle_irq,
758 .init_machine = corgi_init, 761 .init_machine = corgi_init,
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index fb5a51d834e..67f0de37f46 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -274,6 +274,7 @@ static void __init csb726_init(void)
274MACHINE_START(CSB726, "Cogent CSB726") 274MACHINE_START(CSB726, "Cogent CSB726")
275 .atag_offset = 0x100, 275 .atag_offset = 0x100,
276 .map_io = pxa27x_map_io, 276 .map_io = pxa27x_map_io,
277 .nr_irqs = PXA_NR_IRQS,
277 .init_irq = pxa27x_init_irq, 278 .init_irq = pxa27x_init_irq,
278 .handle_irq = pxa27x_handle_irq, 279 .handle_irq = pxa27x_handle_irq,
279 .init_machine = csb726_init, 280 .init_machine = csb726_init,
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 84f2d7015cf..166eee5b8a7 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -12,6 +12,7 @@
12#include <mach/pxafb.h> 12#include <mach/pxafb.h>
13#include <mach/mmc.h> 13#include <mach/mmc.h>
14#include <mach/irda.h> 14#include <mach/irda.h>
15#include <mach/irqs.h>
15#include <mach/ohci.h> 16#include <mach/ohci.h>
16#include <plat/pxa27x_keypad.h> 17#include <plat/pxa27x_keypad.h>
17#include <mach/camera.h> 18#include <mach/camera.h>
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index d80c0ba9a09..c1b65da2633 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -1301,6 +1301,7 @@ static void __init em_x270_init(void)
1301MACHINE_START(EM_X270, "Compulab EM-X270") 1301MACHINE_START(EM_X270, "Compulab EM-X270")
1302 .atag_offset = 0x100, 1302 .atag_offset = 0x100,
1303 .map_io = pxa27x_map_io, 1303 .map_io = pxa27x_map_io,
1304 .nr_irqs = PXA_NR_IRQS,
1304 .init_irq = pxa27x_init_irq, 1305 .init_irq = pxa27x_init_irq,
1305 .handle_irq = pxa27x_handle_irq, 1306 .handle_irq = pxa27x_handle_irq,
1306 .timer = &pxa_timer, 1307 .timer = &pxa_timer,
@@ -1311,6 +1312,7 @@ MACHINE_END
1311MACHINE_START(EXEDA, "Compulab eXeda") 1312MACHINE_START(EXEDA, "Compulab eXeda")
1312 .atag_offset = 0x100, 1313 .atag_offset = 0x100,
1313 .map_io = pxa27x_map_io, 1314 .map_io = pxa27x_map_io,
1315 .nr_irqs = PXA_NR_IRQS,
1314 .init_irq = pxa27x_init_irq, 1316 .init_irq = pxa27x_init_irq,
1315 .handle_irq = pxa27x_handle_irq, 1317 .handle_irq = pxa27x_handle_irq,
1316 .timer = &pxa_timer, 1318 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index ac3b1cef475..e529a35a44c 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -235,6 +235,7 @@ static void __init gumstix_init(void)
235MACHINE_START(GUMSTIX, "Gumstix") 235MACHINE_START(GUMSTIX, "Gumstix")
236 .atag_offset = 0x100, /* match u-boot bi_boot_params */ 236 .atag_offset = 0x100, /* match u-boot bi_boot_params */
237 .map_io = pxa25x_map_io, 237 .map_io = pxa25x_map_io,
238 .nr_irqs = PXA_NR_IRQS,
238 .init_irq = pxa25x_init_irq, 239 .init_irq = pxa25x_init_irq,
239 .handle_irq = pxa25x_handle_irq, 240 .handle_irq = pxa25x_handle_irq,
240 .timer = &pxa_timer, 241 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c
index fde6b4c873c..e7dec589f01 100644
--- a/arch/arm/mach-pxa/h5000.c
+++ b/arch/arm/mach-pxa/h5000.c
@@ -205,6 +205,7 @@ static void __init h5000_init(void)
205MACHINE_START(H5400, "HP iPAQ H5000") 205MACHINE_START(H5400, "HP iPAQ H5000")
206 .atag_offset = 0x100, 206 .atag_offset = 0x100,
207 .map_io = pxa25x_map_io, 207 .map_io = pxa25x_map_io,
208 .nr_irqs = PXA_NR_IRQS,
208 .init_irq = pxa25x_init_irq, 209 .init_irq = pxa25x_init_irq,
209 .handle_irq = pxa25x_handle_irq, 210 .handle_irq = pxa25x_handle_irq,
210 .timer = &pxa_timer, 211 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c
index 26d069a9f90..2962de898da 100644
--- a/arch/arm/mach-pxa/himalaya.c
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -160,6 +160,7 @@ static void __init himalaya_init(void)
160MACHINE_START(HIMALAYA, "HTC Himalaya") 160MACHINE_START(HIMALAYA, "HTC Himalaya")
161 .atag_offset = 0x100, 161 .atag_offset = 0x100,
162 .map_io = pxa25x_map_io, 162 .map_io = pxa25x_map_io,
163 .nr_irqs = PXA_NR_IRQS,
163 .init_irq = pxa25x_init_irq, 164 .init_irq = pxa25x_init_irq,
164 .handle_irq = pxa25x_handle_irq, 165 .handle_irq = pxa25x_handle_irq,
165 .init_machine = himalaya_init, 166 .init_machine = himalaya_init,
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 67400192ed3..1d02eabc9c6 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -193,6 +193,7 @@ static void __init icontrol_init(void)
193MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") 193MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
194 .atag_offset = 0x100, 194 .atag_offset = 0x100,
195 .map_io = pxa3xx_map_io, 195 .map_io = pxa3xx_map_io,
196 .nr_irqs = PXA_NR_IRQS,
196 .init_irq = pxa3xx_init_irq, 197 .init_irq = pxa3xx_init_irq,
197 .handle_irq = pxa3xx_handle_irq, 198 .handle_irq = pxa3xx_handle_irq,
198 .timer = &pxa_timer, 199 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 8af1840e12c..6ff466bd43e 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -195,6 +195,7 @@ static void __init idp_map_io(void)
195MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") 195MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
196 /* Maintainer: Vibren Technologies */ 196 /* Maintainer: Vibren Technologies */
197 .map_io = idp_map_io, 197 .map_io = idp_map_io,
198 .nr_irqs = PXA_NR_IRQS,
198 .init_irq = pxa25x_init_irq, 199 .init_irq = pxa25x_init_irq,
199 .handle_irq = pxa25x_handle_irq, 200 .handle_irq = pxa25x_handle_irq,
200 .timer = &pxa_timer, 201 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 32975adf3ca..8765782dd95 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -100,7 +100,7 @@
100 */ 100 */
101#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO) 101#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO)
102 102
103#define NR_IRQS (IRQ_BOARD_START) 103#define PXA_NR_IRQS (IRQ_BOARD_START)
104 104
105#ifndef __ASSEMBLY__ 105#ifndef __ASSEMBLY__
106struct irq_data; 106struct irq_data;
diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h
index 4c2d11cd824..1bfc4e822a4 100644
--- a/arch/arm/mach-pxa/include/mach/mainstone.h
+++ b/arch/arm/mach-pxa/include/mach/mainstone.h
@@ -13,6 +13,8 @@
13#ifndef ASM_ARCH_MAINSTONE_H 13#ifndef ASM_ARCH_MAINSTONE_H
14#define ASM_ARCH_MAINSTONE_H 14#define ASM_ARCH_MAINSTONE_H
15 15
16#include <mach/irqs.h>
17
16#define MST_ETH_PHYS PXA_CS4_PHYS 18#define MST_ETH_PHYS PXA_CS4_PHYS
17 19
18#define MST_FPGA_PHYS PXA_CS2_PHYS 20#define MST_FPGA_PHYS PXA_CS2_PHYS
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index e80a3db735c..061d57009ce 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -758,6 +758,7 @@ MACHINE_START(MIOA701, "MIO A701")
758 .atag_offset = 0x100, 758 .atag_offset = 0x100,
759 .restart_mode = 's', 759 .restart_mode = 's',
760 .map_io = &pxa27x_map_io, 760 .map_io = &pxa27x_map_io,
761 .nr_irqs = PXA_NR_IRQS,
761 .init_irq = &pxa27x_init_irq, 762 .init_irq = &pxa27x_init_irq,
762 .handle_irq = &pxa27x_handle_irq, 763 .handle_irq = &pxa27x_handle_irq,
763 .init_machine = mioa701_machine_init, 764 .init_machine = mioa701_machine_init,
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
index 169bf8f97af..152efbf093f 100644
--- a/arch/arm/mach-pxa/mp900.c
+++ b/arch/arm/mach-pxa/mp900.c
@@ -95,6 +95,7 @@ MACHINE_START(NEC_MP900, "MobilePro900/C")
95 .atag_offset = 0x220100, 95 .atag_offset = 0x220100,
96 .timer = &pxa_timer, 96 .timer = &pxa_timer,
97 .map_io = pxa25x_map_io, 97 .map_io = pxa25x_map_io,
98 .nr_irqs = PXA_NR_IRQS,
98 .init_irq = pxa25x_init_irq, 99 .init_irq = pxa25x_init_irq,
99 .handle_irq = pxa25x_handle_irq, 100 .handle_irq = pxa25x_handle_irq,
100 .init_machine = mp900c_init, 101 .init_machine = mp900c_init,
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index 1fa80f4f80c..31e0433d83b 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -344,6 +344,7 @@ static void __init palmld_init(void)
344MACHINE_START(PALMLD, "Palm LifeDrive") 344MACHINE_START(PALMLD, "Palm LifeDrive")
345 .atag_offset = 0x100, 345 .atag_offset = 0x100,
346 .map_io = palmld_map_io, 346 .map_io = palmld_map_io,
347 .nr_irqs = PXA_NR_IRQS,
347 .init_irq = pxa27x_init_irq, 348 .init_irq = pxa27x_init_irq,
348 .handle_irq = pxa27x_handle_irq, 349 .handle_irq = pxa27x_handle_irq,
349 .timer = &pxa_timer, 350 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 5ba14316bd9..0f6bd4fcfa3 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -205,6 +205,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
205 .atag_offset = 0x100, 205 .atag_offset = 0x100,
206 .map_io = pxa27x_map_io, 206 .map_io = pxa27x_map_io,
207 .reserve = palmt5_reserve, 207 .reserve = palmt5_reserve,
208 .nr_irqs = PXA_NR_IRQS,
208 .init_irq = pxa27x_init_irq, 209 .init_irq = pxa27x_init_irq,
209 .handle_irq = pxa27x_handle_irq, 210 .handle_irq = pxa27x_handle_irq,
210 .timer = &pxa_timer, 211 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index 29b51b40f09..e2d97eed07a 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -539,6 +539,7 @@ static void __init palmtc_init(void)
539MACHINE_START(PALMTC, "Palm Tungsten|C") 539MACHINE_START(PALMTC, "Palm Tungsten|C")
540 .atag_offset = 0x100, 540 .atag_offset = 0x100,
541 .map_io = pxa25x_map_io, 541 .map_io = pxa25x_map_io,
542 .nr_irqs = PXA_NR_IRQS,
542 .init_irq = pxa25x_init_irq, 543 .init_irq = pxa25x_init_irq,
543 .handle_irq = pxa25x_handle_irq, 544 .handle_irq = pxa25x_handle_irq,
544 .timer = &pxa_timer, 545 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index 5ebf49acb82..c054827c567 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -358,6 +358,7 @@ static void __init palmte2_init(void)
358MACHINE_START(PALMTE2, "Palm Tungsten|E2") 358MACHINE_START(PALMTE2, "Palm Tungsten|E2")
359 .atag_offset = 0x100, 359 .atag_offset = 0x100,
360 .map_io = pxa25x_map_io, 360 .map_io = pxa25x_map_io,
361 .nr_irqs = PXA_NR_IRQS,
361 .init_irq = pxa25x_init_irq, 362 .init_irq = pxa25x_init_irq,
362 .handle_irq = pxa25x_handle_irq, 363 .handle_irq = pxa25x_handle_irq,
363 .timer = &pxa_timer, 364 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index ec8249156c0..fbdebee39a5 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -448,6 +448,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
448 .atag_offset = 0x100, 448 .atag_offset = 0x100,
449 .map_io = pxa27x_map_io, 449 .map_io = pxa27x_map_io,
450 .reserve = treo_reserve, 450 .reserve = treo_reserve,
451 .nr_irqs = PXA_NR_IRQS,
451 .init_irq = pxa27x_init_irq, 452 .init_irq = pxa27x_init_irq,
452 .handle_irq = pxa27x_handle_irq, 453 .handle_irq = pxa27x_handle_irq,
453 .timer = &pxa_timer, 454 .timer = &pxa_timer,
@@ -461,6 +462,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
461 .atag_offset = 0x100, 462 .atag_offset = 0x100,
462 .map_io = pxa27x_map_io, 463 .map_io = pxa27x_map_io,
463 .reserve = treo_reserve, 464 .reserve = treo_reserve,
465 .nr_irqs = PXA_NR_IRQS,
464 .init_irq = pxa27x_init_irq, 466 .init_irq = pxa27x_init_irq,
465 .handle_irq = pxa27x_handle_irq, 467 .handle_irq = pxa27x_handle_irq,
466 .timer = &pxa_timer, 468 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index 6170d76dfba..9507605ed54 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -366,6 +366,7 @@ static void __init palmtx_init(void)
366MACHINE_START(PALMTX, "Palm T|X") 366MACHINE_START(PALMTX, "Palm T|X")
367 .atag_offset = 0x100, 367 .atag_offset = 0x100,
368 .map_io = palmtx_map_io, 368 .map_io = palmtx_map_io,
369 .nr_irqs = PXA_NR_IRQS,
369 .init_irq = pxa27x_init_irq, 370 .init_irq = pxa27x_init_irq,
370 .handle_irq = pxa27x_handle_irq, 371 .handle_irq = pxa27x_handle_irq,
371 .timer = &pxa_timer, 372 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index b2dff9d415e..a97b59965bb 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -401,6 +401,7 @@ static void __init palmz72_init(void)
401MACHINE_START(PALMZ72, "Palm Zire72") 401MACHINE_START(PALMZ72, "Palm Zire72")
402 .atag_offset = 0x100, 402 .atag_offset = 0x100,
403 .map_io = pxa27x_map_io, 403 .map_io = pxa27x_map_io,
404 .nr_irqs = PXA_NR_IRQS,
404 .init_irq = pxa27x_init_irq, 405 .init_irq = pxa27x_init_irq,
405 .handle_irq = pxa27x_handle_irq, 406 .handle_irq = pxa27x_handle_irq,
406 .timer = &pxa_timer, 407 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 1570d457fea..dffb7e813d9 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -31,6 +31,7 @@
31#include <mach/pm.h> 31#include <mach/pm.h>
32#include <mach/dma.h> 32#include <mach/dma.h>
33#include <mach/smemc.h> 33#include <mach/smemc.h>
34#include <mach/irqs.h>
34 35
35#include "generic.h" 36#include "generic.h"
36#include "devices.h" 37#include "devices.h"
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 22818c7694a..7d691e51cb5 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -1090,6 +1090,7 @@ MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
1090 .atag_offset = 0x100, 1090 .atag_offset = 0x100,
1091 .init_machine = raumfeld_controller_init, 1091 .init_machine = raumfeld_controller_init,
1092 .map_io = pxa3xx_map_io, 1092 .map_io = pxa3xx_map_io,
1093 .nr_irqs = PXA_NR_IRQS,
1093 .init_irq = pxa3xx_init_irq, 1094 .init_irq = pxa3xx_init_irq,
1094 .handle_irq = pxa3xx_handle_irq, 1095 .handle_irq = pxa3xx_handle_irq,
1095 .timer = &pxa_timer, 1096 .timer = &pxa_timer,
@@ -1102,6 +1103,7 @@ MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
1102 .atag_offset = 0x100, 1103 .atag_offset = 0x100,
1103 .init_machine = raumfeld_connector_init, 1104 .init_machine = raumfeld_connector_init,
1104 .map_io = pxa3xx_map_io, 1105 .map_io = pxa3xx_map_io,
1106 .nr_irqs = PXA_NR_IRQS,
1105 .init_irq = pxa3xx_init_irq, 1107 .init_irq = pxa3xx_init_irq,
1106 .handle_irq = pxa3xx_handle_irq, 1108 .handle_irq = pxa3xx_handle_irq,
1107 .timer = &pxa_timer, 1109 .timer = &pxa_timer,
@@ -1114,6 +1116,7 @@ MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
1114 .atag_offset = 0x100, 1116 .atag_offset = 0x100,
1115 .init_machine = raumfeld_speaker_init, 1117 .init_machine = raumfeld_speaker_init,
1116 .map_io = pxa3xx_map_io, 1118 .map_io = pxa3xx_map_io,
1119 .nr_irqs = PXA_NR_IRQS,
1117 .init_irq = pxa3xx_init_irq, 1120 .init_irq = pxa3xx_init_irq,
1118 .handle_irq = pxa3xx_handle_irq, 1121 .handle_irq = pxa3xx_handle_irq,
1119 .timer = &pxa_timer, 1122 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index 0fe354efb93..86c95a5d853 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -598,6 +598,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
598 /* Maintainer: Eric Miao <eric.miao@marvell.com> */ 598 /* Maintainer: Eric Miao <eric.miao@marvell.com> */
599 .atag_offset = 0x100, 599 .atag_offset = 0x100,
600 .map_io = pxa3xx_map_io, 600 .map_io = pxa3xx_map_io,
601 .nr_irqs = PXA_NR_IRQS,
601 .init_irq = pxa3xx_init_irq, 602 .init_irq = pxa3xx_init_irq,
602 .handle_irq = pxa3xx_handle_irq, 603 .handle_irq = pxa3xx_handle_irq,
603 .timer = &pxa_timer, 604 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index abf355d0c92..df2ab0fb2ac 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -984,6 +984,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
984 .restart_mode = 'g', 984 .restart_mode = 'g',
985 .fixup = spitz_fixup, 985 .fixup = spitz_fixup,
986 .map_io = pxa27x_map_io, 986 .map_io = pxa27x_map_io,
987 .nr_irqs = PXA_NR_IRQS,
987 .init_irq = pxa27x_init_irq, 988 .init_irq = pxa27x_init_irq,
988 .handle_irq = pxa27x_handle_irq, 989 .handle_irq = pxa27x_handle_irq,
989 .init_machine = spitz_init, 990 .init_machine = spitz_init,
@@ -997,6 +998,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
997 .restart_mode = 'g', 998 .restart_mode = 'g',
998 .fixup = spitz_fixup, 999 .fixup = spitz_fixup,
999 .map_io = pxa27x_map_io, 1000 .map_io = pxa27x_map_io,
1001 .nr_irqs = PXA_NR_IRQS,
1000 .init_irq = pxa27x_init_irq, 1002 .init_irq = pxa27x_init_irq,
1001 .handle_irq = pxa27x_handle_irq, 1003 .handle_irq = pxa27x_handle_irq,
1002 .init_machine = spitz_init, 1004 .init_machine = spitz_init,
@@ -1010,6 +1012,7 @@ MACHINE_START(AKITA, "SHARP Akita")
1010 .restart_mode = 'g', 1012 .restart_mode = 'g',
1011 .fixup = spitz_fixup, 1013 .fixup = spitz_fixup,
1012 .map_io = pxa27x_map_io, 1014 .map_io = pxa27x_map_io,
1015 .nr_irqs = PXA_NR_IRQS,
1013 .init_irq = pxa27x_init_irq, 1016 .init_irq = pxa27x_init_irq,
1014 .handle_irq = pxa27x_handle_irq, 1017 .handle_irq = pxa27x_handle_irq,
1015 .init_machine = spitz_init, 1018 .init_machine = spitz_init,
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index b0656e158d9..adb601a3762 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -1006,6 +1006,7 @@ static void __init stargate2_init(void)
1006#ifdef CONFIG_MACH_INTELMOTE2 1006#ifdef CONFIG_MACH_INTELMOTE2
1007MACHINE_START(INTELMOTE2, "IMOTE 2") 1007MACHINE_START(INTELMOTE2, "IMOTE 2")
1008 .map_io = pxa27x_map_io, 1008 .map_io = pxa27x_map_io,
1009 .nr_irqs = PXA_NR_IRQS,
1009 .init_irq = pxa27x_init_irq, 1010 .init_irq = pxa27x_init_irq,
1010 .handle_irq = pxa27x_handle_irq, 1011 .handle_irq = pxa27x_handle_irq,
1011 .timer = &pxa_timer, 1012 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index 9fb38e80e07..736bfdc50ee 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -491,6 +491,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
491 /* Maintainer: Eric Miao <eric.miao@marvell.com> */ 491 /* Maintainer: Eric Miao <eric.miao@marvell.com> */
492 .atag_offset = 0x100, 492 .atag_offset = 0x100,
493 .map_io = pxa3xx_map_io, 493 .map_io = pxa3xx_map_io,
494 .nr_irqs = PXA_NR_IRQS,
494 .init_irq = pxa3xx_init_irq, 495 .init_irq = pxa3xx_init_irq,
495 .handle_irq = pxa3xx_handle_irq, 496 .handle_irq = pxa3xx_handle_irq,
496 .timer = &pxa_timer, 497 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index b503049d6d2..3d6c9bd90de 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -22,6 +22,7 @@
22#include <asm/mach/time.h> 22#include <asm/mach/time.h>
23#include <asm/sched_clock.h> 23#include <asm/sched_clock.h>
24#include <mach/regs-ost.h> 24#include <mach/regs-ost.h>
25#include <mach/irqs.h>
25 26
26/* 27/*
27 * This is PXA's sched_clock implementation. This has a resolution 28 * This is PXA's sched_clock implementation. This has a resolution
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 0f30af617d8..2b6ac00b2cd 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -558,6 +558,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
558 .atag_offset = 0x100, 558 .atag_offset = 0x100,
559 .init_machine = trizeps4_init, 559 .init_machine = trizeps4_init,
560 .map_io = trizeps4_map_io, 560 .map_io = trizeps4_map_io,
561 .nr_irqs = PXA_NR_IRQS,
561 .init_irq = pxa27x_init_irq, 562 .init_irq = pxa27x_init_irq,
562 .handle_irq = pxa27x_handle_irq, 563 .handle_irq = pxa27x_handle_irq,
563 .timer = &pxa_timer, 564 .timer = &pxa_timer,
@@ -569,6 +570,7 @@ MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")
569 .atag_offset = 0x100, 570 .atag_offset = 0x100,
570 .init_machine = trizeps4_init, 571 .init_machine = trizeps4_init,
571 .map_io = trizeps4_map_io, 572 .map_io = trizeps4_map_io,
573 .nr_irqs = PXA_NR_IRQS,
572 .init_irq = pxa27x_init_irq, 574 .init_irq = pxa27x_init_irq,
573 .handle_irq = pxa27x_handle_irq, 575 .handle_irq = pxa27x_handle_irq,
574 .timer = &pxa_timer, 576 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 7a3d342a773..130379fb9d0 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -995,6 +995,7 @@ MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC")
995 /* Maintainer: Marc Zyngier <maz@misterjones.org> */ 995 /* Maintainer: Marc Zyngier <maz@misterjones.org> */
996 .atag_offset = 0x100, 996 .atag_offset = 0x100,
997 .map_io = viper_map_io, 997 .map_io = viper_map_io,
998 .nr_irqs = PXA_NR_IRQS,
998 .init_irq = viper_init_irq, 999 .init_irq = viper_init_irq,
999 .handle_irq = pxa25x_handle_irq, 1000 .handle_irq = pxa25x_handle_irq,
1000 .timer = &pxa_timer, 1001 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
index 1f5cfa96f6d..c57ab636ea9 100644
--- a/arch/arm/mach-pxa/vpac270.c
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -718,6 +718,7 @@ static void __init vpac270_init(void)
718MACHINE_START(VPAC270, "Voipac PXA270") 718MACHINE_START(VPAC270, "Voipac PXA270")
719 .atag_offset = 0x100, 719 .atag_offset = 0x100,
720 .map_io = pxa27x_map_io, 720 .map_io = pxa27x_map_io,
721 .nr_irqs = PXA_NR_IRQS,
721 .init_irq = pxa27x_init_irq, 722 .init_irq = pxa27x_init_irq,
722 .handle_irq = pxa27x_handle_irq, 723 .handle_irq = pxa27x_handle_irq,
723 .timer = &pxa_timer, 724 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c
index 4bbe9a36fe7..4275713ccd1 100644
--- a/arch/arm/mach-pxa/xcep.c
+++ b/arch/arm/mach-pxa/xcep.c
@@ -182,6 +182,7 @@ MACHINE_START(XCEP, "Iskratel XCEP")
182 .atag_offset = 0x100, 182 .atag_offset = 0x100,
183 .init_machine = xcep_init, 183 .init_machine = xcep_init,
184 .map_io = pxa25x_map_io, 184 .map_io = pxa25x_map_io,
185 .nr_irqs = PXA_NR_IRQS,
185 .init_irq = pxa25x_init_irq, 186 .init_irq = pxa25x_init_irq,
186 .handle_irq = pxa25x_handle_irq, 187 .handle_irq = pxa25x_handle_irq,
187 .timer = &pxa_timer, 188 .timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index b6476848b56..fa861997084 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -721,6 +721,7 @@ static void __init z2_init(void)
721MACHINE_START(ZIPIT2, "Zipit Z2") 721MACHINE_START(ZIPIT2, "Zipit Z2")
722 .atag_offset = 0x100, 722 .atag_offset = 0x100,
723 .map_io = pxa27x_map_io, 723 .map_io = pxa27x_map_io,
724 .nr_irqs = PXA_NR_IRQS,
724 .init_irq = pxa27x_init_irq, 725 .init_irq = pxa27x_init_irq,
725 .handle_irq = pxa27x_handle_irq, 726 .handle_irq = pxa27x_handle_irq,
726 .timer = &pxa_timer, 727 .timer = &pxa_timer,
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 060e5644c49..34560cab45d 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -100,6 +100,10 @@ config MACH_MARZEN
100 100
101comment "SH-Mobile System Configuration" 101comment "SH-Mobile System Configuration"
102 102
103config CPU_HAS_INTEVT
104 bool
105 default y
106
103menu "Memory configuration" 107menu "Memory configuration"
104 108
105config MEMORY_START 109config MEMORY_START
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index f50d7c8b122..f9153294e92 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -43,6 +43,7 @@
43#include <video/sh_mipi_dsi.h> 43#include <video/sh_mipi_dsi.h>
44#include <sound/sh_fsi.h> 44#include <sound/sh_fsi.h>
45#include <mach/hardware.h> 45#include <mach/hardware.h>
46#include <mach/irqs.h>
46#include <mach/sh73a0.h> 47#include <mach/sh73a0.h>
47#include <mach/common.h> 48#include <mach/common.h>
48#include <asm/mach-types.h> 49#include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
index 8b2124da245..a71ae802cc4 100644
--- a/arch/arm/mach-shmobile/board-bonito.c
+++ b/arch/arm/mach-shmobile/board-bonito.c
@@ -35,6 +35,7 @@
35#include <asm/mach/time.h> 35#include <asm/mach/time.h>
36#include <asm/hardware/cache-l2x0.h> 36#include <asm/hardware/cache-l2x0.h>
37#include <mach/r8a7740.h> 37#include <mach/r8a7740.h>
38#include <mach/irqs.h>
38#include <video/sh_mobile_lcdc.h> 39#include <video/sh_mobile_lcdc.h>
39 40
40/* 41/*
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index b627e89037f..39b6cf85ced 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -33,6 +33,7 @@
33#include <linux/input.h> 33#include <linux/input.h>
34#include <linux/input/sh_keysc.h> 34#include <linux/input/sh_keysc.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <mach/irqs.h>
36#include <mach/sh7367.h> 37#include <mach/sh7367.h>
37#include <mach/common.h> 38#include <mach/common.h>
38#include <asm/mach-types.h> 39#include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 46d757d2759..0e5a39c670b 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -34,6 +34,7 @@
34#include <linux/mmc/sh_mobile_sdhi.h> 34#include <linux/mmc/sh_mobile_sdhi.h>
35#include <linux/gpio.h> 35#include <linux/gpio.h>
36#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
37#include <mach/irqs.h>
37#include <mach/sh7377.h> 38#include <mach/sh7377.h>
38#include <mach/common.h> 39#include <mach/common.h>
39#include <asm/mach-types.h> 40#include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 61c06729466..10e9e696790 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -39,6 +39,7 @@
39#include <linux/mfd/tmio.h> 39#include <linux/mfd/tmio.h>
40#include <linux/mmc/sh_mobile_sdhi.h> 40#include <linux/mmc/sh_mobile_sdhi.h>
41#include <mach/hardware.h> 41#include <mach/hardware.h>
42#include <mach/irqs.h>
42#include <mach/sh73a0.h> 43#include <mach/sh73a0.h>
43#include <mach/common.h> 44#include <mach/common.h>
44#include <asm/mach-types.h> 45#include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index ca609502d6c..a125d4e114e 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -54,6 +54,7 @@
54#include <sound/sh_fsi.h> 54#include <sound/sh_fsi.h>
55 55
56#include <mach/common.h> 56#include <mach/common.h>
57#include <mach/irqs.h>
57#include <mach/sh7372.h> 58#include <mach/sh7372.h>
58 59
59#include <asm/mach/arch.h> 60#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index cbd5e4cd06d..ef0e13bf0b3 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -31,6 +31,7 @@
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <mach/r8a7779.h> 32#include <mach/r8a7779.h>
33#include <mach/common.h> 33#include <mach/common.h>
34#include <mach/irqs.h>
34#include <asm/mach-types.h> 35#include <asm/mach-types.h>
35#include <asm/mach/arch.h> 36#include <asm/mach/arch.h>
36#include <asm/hardware/gic.h> 37#include <asm/hardware/gic.h>
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
index dcb714f4d75..4e686cc201f 100644
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -1,15 +1,11 @@
1#ifndef __ASM_MACH_IRQS_H 1#ifndef __ASM_MACH_IRQS_H
2#define __ASM_MACH_IRQS_H 2#define __ASM_MACH_IRQS_H
3 3
4#define NR_IRQS 1024 4#include <linux/sh_intc.h>
5 5
6/* GIC */ 6/* GIC */
7#define gic_spi(nr) ((nr) + 32) 7#define gic_spi(nr) ((nr) + 32)
8 8
9/* INTCA */
10#define evt2irq(evt) (((evt) >> 5) - 16)
11#define irq2evt(irq) (((irq) + 16) << 5)
12
13/* INTCS */ 9/* INTCS */
14#define INTCS_VECT_BASE 0x2200 10#define INTCS_VECT_BASE 0x2200
15#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect)) 11#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c
index 272c84c20c8..09c42afcb22 100644
--- a/arch/arm/mach-shmobile/intc-r8a7740.c
+++ b/arch/arm/mach-shmobile/intc-r8a7740.c
@@ -25,6 +25,7 @@
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/sh_intc.h> 26#include <linux/sh_intc.h>
27#include <mach/intc.h> 27#include <mach/intc.h>
28#include <mach/irqs.h>
28#include <asm/mach-types.h> 29#include <asm/mach-types.h>
29#include <asm/mach/arch.h> 30#include <asm/mach/arch.h>
30 31
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
index cfde9bfc366..5bf776495b7 100644
--- a/arch/arm/mach-shmobile/intc-sh7367.c
+++ b/arch/arm/mach-shmobile/intc-sh7367.c
@@ -23,6 +23,7 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/sh_intc.h> 24#include <linux/sh_intc.h>
25#include <mach/intc.h> 25#include <mach/intc.h>
26#include <mach/irqs.h>
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
27#include <asm/mach/arch.h> 28#include <asm/mach/arch.h>
28 29
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index 89afcaba99a..6447e0af52d 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -23,6 +23,7 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/sh_intc.h> 24#include <linux/sh_intc.h>
25#include <mach/intc.h> 25#include <mach/intc.h>
26#include <mach/irqs.h>
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
27#include <asm/mach/arch.h> 28#include <asm/mach/arch.h>
28 29
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
index 2af4e6e9bc5..b84a460a340 100644
--- a/arch/arm/mach-shmobile/intc-sh7377.c
+++ b/arch/arm/mach-shmobile/intc-sh7377.c
@@ -23,6 +23,7 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/sh_intc.h> 24#include <linux/sh_intc.h>
25#include <mach/intc.h> 25#include <mach/intc.h>
26#include <mach/irqs.h>
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
27#include <asm/mach/arch.h> 28#include <asm/mach/arch.h>
28 29
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index 9857595eaa7..15b408f5827 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -24,6 +24,7 @@
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/sh_intc.h> 25#include <linux/sh_intc.h>
26#include <mach/intc.h> 26#include <mach/intc.h>
27#include <mach/irqs.h>
27#include <mach/sh73a0.h> 28#include <mach/sh73a0.h>
28#include <asm/hardware/gic.h> 29#include <asm/hardware/gic.h>
29#include <asm/mach-types.h> 30#include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 74e52341dd1..14edb5cffa7 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -26,6 +26,7 @@
26#include <linux/sh_timer.h> 26#include <linux/sh_timer.h>
27#include <mach/r8a7740.h> 27#include <mach/r8a7740.h>
28#include <mach/common.h> 28#include <mach/common.h>
29#include <mach/irqs.h>
29#include <asm/mach-types.h> 30#include <asm/mach-types.h>
30#include <asm/mach/map.h> 31#include <asm/mach/map.h>
31#include <asm/mach/arch.h> 32#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 6820d785493..12c6f529ab8 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -29,6 +29,7 @@
29#include <linux/sh_intc.h> 29#include <linux/sh_intc.h>
30#include <linux/sh_timer.h> 30#include <linux/sh_timer.h>
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <mach/irqs.h>
32#include <mach/r8a7779.h> 33#include <mach/r8a7779.h>
33#include <mach/common.h> 34#include <mach/common.h>
34#include <asm/mach-types.h> 35#include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index a51e1a1e699..2e3074ab75b 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -30,6 +30,7 @@
30#include <linux/sh_timer.h> 30#include <linux/sh_timer.h>
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <mach/common.h> 32#include <mach/common.h>
33#include <mach/irqs.h>
33#include <asm/mach-types.h> 34#include <asm/mach-types.h>
34#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
35#include <asm/mach/map.h> 36#include <asm/mach/map.h>
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 4e818b7de78..2fe8f83ca12 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -33,6 +33,7 @@
33#include <linux/pm_domain.h> 33#include <linux/pm_domain.h>
34#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
35#include <mach/hardware.h> 35#include <mach/hardware.h>
36#include <mach/irqs.h>
36#include <mach/sh7372.h> 37#include <mach/sh7372.h>
37#include <mach/common.h> 38#include <mach/common.h>
38#include <asm/mach/map.h> 39#include <asm/mach/map.h>
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index 9f146095098..d576a6abbad 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -32,6 +32,7 @@
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/common.h> 33#include <mach/common.h>
34#include <asm/mach/map.h> 34#include <asm/mach/map.h>
35#include <mach/irqs.h>
35#include <asm/mach-types.h> 36#include <asm/mach-types.h>
36#include <asm/mach/arch.h> 37#include <asm/mach/arch.h>
37#include <asm/mach/time.h> 38#include <asm/mach/time.h>
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index b6a0734a738..5bebffc1045 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -31,6 +31,7 @@
31#include <linux/sh_intc.h> 31#include <linux/sh_intc.h>
32#include <linux/sh_timer.h> 32#include <linux/sh_timer.h>
33#include <mach/hardware.h> 33#include <mach/hardware.h>
34#include <mach/irqs.h>
34#include <mach/sh73a0.h> 35#include <mach/sh73a0.h>
35#include <mach/common.h> 36#include <mach/common.h>
36#include <asm/mach-types.h> 37#include <asm/mach-types.h>
diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h
index 13522d86685..0088cd388a8 100644
--- a/arch/arm/mach-vexpress/include/mach/io.h
+++ b/arch/arm/mach-vexpress/include/mach/io.h
@@ -20,7 +20,6 @@
20#ifndef __ASM_ARM_ARCH_IO_H 20#ifndef __ASM_ARM_ARCH_IO_H
21#define __ASM_ARM_ARCH_IO_H 21#define __ASM_ARM_ARCH_IO_H
22 22
23#define __io(a) __typesafe_io(a)
24#define __mem_pci(a) (a) 23#define __mem_pci(a) (a)
25 24
26#endif 25#endif
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index b1e192ba8c2..a53fd2aaa2f 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -30,13 +30,13 @@
30 30
31static void __iomem *l2x0_base; 31static void __iomem *l2x0_base;
32static DEFINE_RAW_SPINLOCK(l2x0_lock); 32static DEFINE_RAW_SPINLOCK(l2x0_lock);
33static uint32_t l2x0_way_mask; /* Bitmask of active ways */ 33static u32 l2x0_way_mask; /* Bitmask of active ways */
34static uint32_t l2x0_size; 34static u32 l2x0_size;
35 35
36struct l2x0_regs l2x0_saved_regs; 36struct l2x0_regs l2x0_saved_regs;
37 37
38struct l2x0_of_data { 38struct l2x0_of_data {
39 void (*setup)(const struct device_node *, __u32 *, __u32 *); 39 void (*setup)(const struct device_node *, u32 *, u32 *);
40 void (*save)(void); 40 void (*save)(void);
41 void (*resume)(void); 41 void (*resume)(void);
42}; 42};
@@ -288,7 +288,7 @@ static void l2x0_disable(void)
288 raw_spin_unlock_irqrestore(&l2x0_lock, flags); 288 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
289} 289}
290 290
291static void l2x0_unlock(__u32 cache_id) 291static void l2x0_unlock(u32 cache_id)
292{ 292{
293 int lockregs; 293 int lockregs;
294 int i; 294 int i;
@@ -307,11 +307,11 @@ static void l2x0_unlock(__u32 cache_id)
307 } 307 }
308} 308}
309 309
310void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) 310void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
311{ 311{
312 __u32 aux; 312 u32 aux;
313 __u32 cache_id; 313 u32 cache_id;
314 __u32 way_size = 0; 314 u32 way_size = 0;
315 int ways; 315 int ways;
316 const char *type; 316 const char *type;
317 317
@@ -388,7 +388,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
388 388
389#ifdef CONFIG_OF 389#ifdef CONFIG_OF
390static void __init l2x0_of_setup(const struct device_node *np, 390static void __init l2x0_of_setup(const struct device_node *np,
391 __u32 *aux_val, __u32 *aux_mask) 391 u32 *aux_val, u32 *aux_mask)
392{ 392{
393 u32 data[2] = { 0, 0 }; 393 u32 data[2] = { 0, 0 };
394 u32 tag = 0; 394 u32 tag = 0;
@@ -422,7 +422,7 @@ static void __init l2x0_of_setup(const struct device_node *np,
422} 422}
423 423
424static void __init pl310_of_setup(const struct device_node *np, 424static void __init pl310_of_setup(const struct device_node *np,
425 __u32 *aux_val, __u32 *aux_mask) 425 u32 *aux_val, u32 *aux_mask)
426{ 426{
427 u32 data[3] = { 0, 0, 0 }; 427 u32 data[3] = { 0, 0, 0 };
428 u32 tag[3] = { 0, 0, 0 }; 428 u32 tag[3] = { 0, 0, 0 };
@@ -548,7 +548,7 @@ static const struct of_device_id l2x0_ids[] __initconst = {
548 {} 548 {}
549}; 549};
550 550
551int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask) 551int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
552{ 552{
553 struct device_node *np; 553 struct device_node *np;
554 struct l2x0_of_data *data; 554 struct l2x0_of_data *data;
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index ec8c3befb9c..1267e64133b 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -23,10 +23,6 @@
23 23
24#include "mm.h" 24#include "mm.h"
25 25
26/*
27 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
28 * specific hacks for copying pages efficiently.
29 */
30#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ 26#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
31 L_PTE_MT_MINICACHE) 27 L_PTE_MT_MINICACHE)
32 28
@@ -78,10 +74,9 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from,
78 74
79 raw_spin_lock(&minicache_lock); 75 raw_spin_lock(&minicache_lock);
80 76
81 set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); 77 set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
82 flush_tlb_kernel_page(0xffff8000);
83 78
84 mc_copy_user_page((void *)0xffff8000, kto); 79 mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
85 80
86 raw_spin_unlock(&minicache_lock); 81 raw_spin_unlock(&minicache_lock);
87 82
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 8b03a5814d0..b9bcc9d7917 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -24,9 +24,6 @@
24#error FIX ME 24#error FIX ME
25#endif 25#endif
26 26
27#define from_address (0xffff8000)
28#define to_address (0xffffc000)
29
30static DEFINE_RAW_SPINLOCK(v6_lock); 27static DEFINE_RAW_SPINLOCK(v6_lock);
31 28
32/* 29/*
@@ -90,14 +87,11 @@ static void v6_copy_user_highpage_aliasing(struct page *to,
90 */ 87 */
91 raw_spin_lock(&v6_lock); 88 raw_spin_lock(&v6_lock);
92 89
93 set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0); 90 kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT);
94 set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0); 91 kto = COPYPAGE_V6_TO + (offset << PAGE_SHIFT);
95
96 kfrom = from_address + (offset << PAGE_SHIFT);
97 kto = to_address + (offset << PAGE_SHIFT);
98 92
99 flush_tlb_kernel_page(kfrom); 93 set_top_pte(kfrom, mk_pte(from, PAGE_KERNEL));
100 flush_tlb_kernel_page(kto); 94 set_top_pte(kto, mk_pte(to, PAGE_KERNEL));
101 95
102 copy_page((void *)kto, (void *)kfrom); 96 copy_page((void *)kto, (void *)kfrom);
103 97
@@ -111,8 +105,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to,
111 */ 105 */
112static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr) 106static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr)
113{ 107{
114 unsigned int offset = CACHE_COLOUR(vaddr); 108 unsigned long to = COPYPAGE_V6_TO + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
115 unsigned long to = to_address + (offset << PAGE_SHIFT);
116 109
117 /* FIXME: not highmem safe */ 110 /* FIXME: not highmem safe */
118 discard_old_kernel_data(page_address(page)); 111 discard_old_kernel_data(page_address(page));
@@ -123,8 +116,7 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad
123 */ 116 */
124 raw_spin_lock(&v6_lock); 117 raw_spin_lock(&v6_lock);
125 118
126 set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0); 119 set_top_pte(to, mk_pte(page, PAGE_KERNEL));
127 flush_tlb_kernel_page(to);
128 clear_page((void *)to); 120 clear_page((void *)to);
129 121
130 raw_spin_unlock(&v6_lock); 122 raw_spin_unlock(&v6_lock);
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 439d106ae63..0fb85025344 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -23,12 +23,6 @@
23 23
24#include "mm.h" 24#include "mm.h"
25 25
26/*
27 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
28 * specific hacks for copying pages efficiently.
29 */
30#define COPYPAGE_MINICACHE 0xffff8000
31
32#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ 26#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
33 L_PTE_MT_MINICACHE) 27 L_PTE_MT_MINICACHE)
34 28
@@ -100,8 +94,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
100 94
101 raw_spin_lock(&minicache_lock); 95 raw_spin_lock(&minicache_lock);
102 96
103 set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); 97 set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
104 flush_tlb_kernel_page(COPYPAGE_MINICACHE);
105 98
106 mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); 99 mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
107 100
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1aa664a1999..db23ae4aaaa 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -214,7 +214,8 @@ static int __init consistent_init(void)
214core_initcall(consistent_init); 214core_initcall(consistent_init);
215 215
216static void * 216static void *
217__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) 217__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
218 const void *caller)
218{ 219{
219 struct arm_vmregion *c; 220 struct arm_vmregion *c;
220 size_t align; 221 size_t align;
@@ -241,7 +242,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
241 * Allocate a virtual address in the consistent mapping region. 242 * Allocate a virtual address in the consistent mapping region.
242 */ 243 */
243 c = arm_vmregion_alloc(&consistent_head, align, size, 244 c = arm_vmregion_alloc(&consistent_head, align, size,
244 gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); 245 gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller);
245 if (c) { 246 if (c) {
246 pte_t *pte; 247 pte_t *pte;
247 int idx = CONSISTENT_PTE_INDEX(c->vm_start); 248 int idx = CONSISTENT_PTE_INDEX(c->vm_start);
@@ -320,14 +321,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
320 321
321#else /* !CONFIG_MMU */ 322#else /* !CONFIG_MMU */
322 323
323#define __dma_alloc_remap(page, size, gfp, prot) page_address(page) 324#define __dma_alloc_remap(page, size, gfp, prot, c) page_address(page)
324#define __dma_free_remap(addr, size) do { } while (0) 325#define __dma_free_remap(addr, size) do { } while (0)
325 326
326#endif /* CONFIG_MMU */ 327#endif /* CONFIG_MMU */
327 328
328static void * 329static void *
329__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, 330__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
330 pgprot_t prot) 331 pgprot_t prot, const void *caller)
331{ 332{
332 struct page *page; 333 struct page *page;
333 void *addr; 334 void *addr;
@@ -349,7 +350,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
349 return NULL; 350 return NULL;
350 351
351 if (!arch_is_coherent()) 352 if (!arch_is_coherent())
352 addr = __dma_alloc_remap(page, size, gfp, prot); 353 addr = __dma_alloc_remap(page, size, gfp, prot, caller);
353 else 354 else
354 addr = page_address(page); 355 addr = page_address(page);
355 356
@@ -374,7 +375,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf
374 return memory; 375 return memory;
375 376
376 return __dma_alloc(dev, size, handle, gfp, 377 return __dma_alloc(dev, size, handle, gfp,
377 pgprot_dmacoherent(pgprot_kernel)); 378 pgprot_dmacoherent(pgprot_kernel),
379 __builtin_return_address(0));
378} 380}
379EXPORT_SYMBOL(dma_alloc_coherent); 381EXPORT_SYMBOL(dma_alloc_coherent);
380 382
@@ -386,7 +388,8 @@ void *
386dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) 388dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
387{ 389{
388 return __dma_alloc(dev, size, handle, gfp, 390 return __dma_alloc(dev, size, handle, gfp,
389 pgprot_writecombine(pgprot_kernel)); 391 pgprot_writecombine(pgprot_kernel),
392 __builtin_return_address(0));
390} 393}
391EXPORT_SYMBOL(dma_alloc_writecombine); 394EXPORT_SYMBOL(dma_alloc_writecombine);
392 395
@@ -723,6 +726,9 @@ EXPORT_SYMBOL(dma_set_mask);
723 726
724static int __init dma_debug_do_init(void) 727static int __init dma_debug_do_init(void)
725{ 728{
729#ifdef CONFIG_MMU
730 arm_vmregion_create_proc("dma-mappings", &consistent_head);
731#endif
726 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); 732 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
727 return 0; 733 return 0;
728} 734}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 5bdff5c3e6c..9055b5a84ec 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -165,7 +165,8 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
165 struct siginfo si; 165 struct siginfo si;
166 166
167#ifdef CONFIG_DEBUG_USER 167#ifdef CONFIG_DEBUG_USER
168 if (user_debug & UDBG_SEGV) { 168 if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
169 ((user_debug & UDBG_BUS) && (sig == SIGBUS))) {
169 printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n", 170 printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
170 tsk->comm, sig, addr, fsr); 171 tsk->comm, sig, addr, fsr);
171 show_pte(tsk->mm, addr); 172 show_pte(tsk->mm, addr);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 062d61a1f87..77458548e03 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -22,15 +22,12 @@
22 22
23#ifdef CONFIG_CPU_CACHE_VIPT 23#ifdef CONFIG_CPU_CACHE_VIPT
24 24
25#define ALIAS_FLUSH_START 0xffff4000
26
27static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) 25static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
28{ 26{
29 unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); 27 unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
30 const int zero = 0; 28 const int zero = 0;
31 29
32 set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0); 30 set_top_pte(to, pfn_pte(pfn, PAGE_KERNEL));
33 flush_tlb_kernel_page(to);
34 31
35 asm( "mcrr p15, 0, %1, %0, c14\n" 32 asm( "mcrr p15, 0, %1, %0, c14\n"
36 " mcr p15, 0, %2, c7, c10, 4" 33 " mcr p15, 0, %2, c7, c10, 4"
@@ -41,13 +38,12 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
41 38
42static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len) 39static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len)
43{ 40{
44 unsigned long colour = CACHE_COLOUR(vaddr); 41 unsigned long va = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
45 unsigned long offset = vaddr & (PAGE_SIZE - 1); 42 unsigned long offset = vaddr & (PAGE_SIZE - 1);
46 unsigned long to; 43 unsigned long to;
47 44
48 set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0); 45 set_top_pte(va, pfn_pte(pfn, PAGE_KERNEL));
49 to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset; 46 to = va + offset;
50 flush_tlb_kernel_page(to);
51 flush_icache_range(to, to + len); 47 flush_icache_range(to, to + len);
52} 48}
53 49
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 5a21505d755..21b9e1bf9b7 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -69,15 +69,14 @@ void *kmap_atomic(struct page *page)
69 * With debugging enabled, kunmap_atomic forces that entry to 0. 69 * With debugging enabled, kunmap_atomic forces that entry to 0.
70 * Make sure it was indeed properly unmapped. 70 * Make sure it was indeed properly unmapped.
71 */ 71 */
72 BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); 72 BUG_ON(!pte_none(get_top_pte(vaddr)));
73#endif 73#endif
74 set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0);
75 /* 74 /*
76 * When debugging is off, kunmap_atomic leaves the previous mapping 75 * When debugging is off, kunmap_atomic leaves the previous mapping
77 * in place, so this TLB flush ensures the TLB is updated with the 76 * in place, so the contained TLB flush ensures the TLB is updated
78 * new mapping. 77 * with the new mapping.
79 */ 78 */
80 local_flush_tlb_kernel_page(vaddr); 79 set_top_pte(vaddr, mk_pte(page, kmap_prot));
81 80
82 return (void *)vaddr; 81 return (void *)vaddr;
83} 82}
@@ -96,8 +95,7 @@ void __kunmap_atomic(void *kvaddr)
96 __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); 95 __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
97#ifdef CONFIG_DEBUG_HIGHMEM 96#ifdef CONFIG_DEBUG_HIGHMEM
98 BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); 97 BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
99 set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); 98 set_top_pte(vaddr, __pte(0));
100 local_flush_tlb_kernel_page(vaddr);
101#else 99#else
102 (void) idx; /* to kill a warning */ 100 (void) idx; /* to kill a warning */
103#endif 101#endif
@@ -121,10 +119,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
121 idx = type + KM_TYPE_NR * smp_processor_id(); 119 idx = type + KM_TYPE_NR * smp_processor_id();
122 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 120 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
123#ifdef CONFIG_DEBUG_HIGHMEM 121#ifdef CONFIG_DEBUG_HIGHMEM
124 BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); 122 BUG_ON(!pte_none(get_top_pte(vaddr)));
125#endif 123#endif
126 set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0); 124 set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
127 local_flush_tlb_kernel_page(vaddr);
128 125
129 return (void *)vaddr; 126 return (void *)vaddr;
130} 127}
@@ -132,11 +129,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
132struct page *kmap_atomic_to_page(const void *ptr) 129struct page *kmap_atomic_to_page(const void *ptr)
133{ 130{
134 unsigned long vaddr = (unsigned long)ptr; 131 unsigned long vaddr = (unsigned long)ptr;
135 pte_t *pte;
136 132
137 if (vaddr < FIXADDR_START) 133 if (vaddr < FIXADDR_START)
138 return virt_to_page(ptr); 134 return virt_to_page(ptr);
139 135
140 pte = TOP_PTE(vaddr); 136 return pte_page(get_top_pte(vaddr));
141 return pte_page(*pte);
142} 137}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 245a55a0a5b..595079fa9d1 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -658,7 +658,9 @@ void __init mem_init(void)
658#ifdef CONFIG_HIGHMEM 658#ifdef CONFIG_HIGHMEM
659 " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n" 659 " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
660#endif 660#endif
661#ifdef CONFIG_MODULES
661 " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" 662 " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
663#endif
662 " .text : 0x%p" " - 0x%p" " (%4d kB)\n" 664 " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
663 " .init : 0x%p" " - 0x%p" " (%4d kB)\n" 665 " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
664 " .data : 0x%p" " - 0x%p" " (%4d kB)\n" 666 " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
@@ -677,7 +679,9 @@ void __init mem_init(void)
677 MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) * 679 MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
678 (PAGE_SIZE)), 680 (PAGE_SIZE)),
679#endif 681#endif
682#ifdef CONFIG_MODULES
680 MLM(MODULES_VADDR, MODULES_END), 683 MLM(MODULES_VADDR, MODULES_END),
684#endif
681 685
682 MLK_ROUNDUP(_text, _etext), 686 MLK_ROUNDUP(_text, _etext),
683 MLK_ROUNDUP(__init_begin, __init_end), 687 MLK_ROUNDUP(__init_begin, __init_end),
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 70f6d3ea483..27f4a619b35 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -3,7 +3,31 @@
3/* the upper-most page table pointer */ 3/* the upper-most page table pointer */
4extern pmd_t *top_pmd; 4extern pmd_t *top_pmd;
5 5
6#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) 6/*
7 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
8 * specific hacks for copying pages efficiently, while 0xffff4000
9 * is reserved for VIPT aliasing flushing by generic code.
10 *
11 * Note that we don't allow VIPT aliasing caches with SMP.
12 */
13#define COPYPAGE_MINICACHE 0xffff8000
14#define COPYPAGE_V6_FROM 0xffff8000
15#define COPYPAGE_V6_TO 0xffffc000
16/* PFN alias flushing, for VIPT caches */
17#define FLUSH_ALIAS_START 0xffff4000
18
19static inline void set_top_pte(unsigned long va, pte_t pte)
20{
21 pte_t *ptep = pte_offset_kernel(top_pmd, va);
22 set_pte_ext(ptep, pte, 0);
23 local_flush_tlb_kernel_page(va);
24}
25
26static inline pte_t get_top_pte(unsigned long va)
27{
28 pte_t *ptep = pte_offset_kernel(top_pmd, va);
29 return *ptep;
30}
7 31
8static inline pmd_t *pmd_off_k(unsigned long virt) 32static inline pmd_t *pmd_off_k(unsigned long virt)
9{ 33{
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index cd439c1dd50..b86f8933ff9 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -999,11 +999,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
999{ 999{
1000 struct map_desc map; 1000 struct map_desc map;
1001 unsigned long addr; 1001 unsigned long addr;
1002 void *vectors;
1002 1003
1003 /* 1004 /*
1004 * Allocate the vector page early. 1005 * Allocate the vector page early.
1005 */ 1006 */
1006 vectors_page = early_alloc(PAGE_SIZE); 1007 vectors = early_alloc(PAGE_SIZE);
1008
1009 early_trap_init(vectors);
1007 1010
1008 for (addr = VMALLOC_START; addr; addr += PMD_SIZE) 1011 for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
1009 pmd_clear(pmd_off_k(addr)); 1012 pmd_clear(pmd_off_k(addr));
@@ -1043,7 +1046,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
1043 * location (0xffff0000). If we aren't using high-vectors, also 1046 * location (0xffff0000). If we aren't using high-vectors, also
1044 * create a mapping at the low-vectors virtual address. 1047 * create a mapping at the low-vectors virtual address.
1045 */ 1048 */
1046 map.pfn = __phys_to_pfn(virt_to_phys(vectors_page)); 1049 map.pfn = __phys_to_pfn(virt_to_phys(vectors));
1047 map.virtual = 0xffff0000; 1050 map.virtual = 0xffff0000;
1048 map.length = PAGE_SIZE; 1051 map.length = PAGE_SIZE;
1049 map.type = MT_HIGH_VECTORS; 1052 map.type = MT_HIGH_VECTORS;
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 036fdbfdd62..a631016e1f8 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -1,5 +1,8 @@
1#include <linux/fs.h>
1#include <linux/spinlock.h> 2#include <linux/spinlock.h>
2#include <linux/list.h> 3#include <linux/list.h>
4#include <linux/proc_fs.h>
5#include <linux/seq_file.h>
3#include <linux/slab.h> 6#include <linux/slab.h>
4 7
5#include "vmregion.h" 8#include "vmregion.h"
@@ -36,7 +39,7 @@
36 39
37struct arm_vmregion * 40struct arm_vmregion *
38arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, 41arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
39 size_t size, gfp_t gfp) 42 size_t size, gfp_t gfp, const void *caller)
40{ 43{
41 unsigned long start = head->vm_start, addr = head->vm_end; 44 unsigned long start = head->vm_start, addr = head->vm_end;
42 unsigned long flags; 45 unsigned long flags;
@@ -52,6 +55,8 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
52 if (!new) 55 if (!new)
53 goto out; 56 goto out;
54 57
58 new->caller = caller;
59
55 spin_lock_irqsave(&head->vm_lock, flags); 60 spin_lock_irqsave(&head->vm_lock, flags);
56 61
57 addr = rounddown(addr - size, align); 62 addr = rounddown(addr - size, align);
@@ -129,3 +134,72 @@ void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)
129 134
130 kfree(c); 135 kfree(c);
131} 136}
137
138#ifdef CONFIG_PROC_FS
139static int arm_vmregion_show(struct seq_file *m, void *p)
140{
141 struct arm_vmregion *c = list_entry(p, struct arm_vmregion, vm_list);
142
143 seq_printf(m, "0x%08lx-0x%08lx %7lu", c->vm_start, c->vm_end,
144 c->vm_end - c->vm_start);
145 if (c->caller)
146 seq_printf(m, " %pS", (void *)c->caller);
147 seq_putc(m, '\n');
148 return 0;
149}
150
151static void *arm_vmregion_start(struct seq_file *m, loff_t *pos)
152{
153 struct arm_vmregion_head *h = m->private;
154 spin_lock_irq(&h->vm_lock);
155 return seq_list_start(&h->vm_list, *pos);
156}
157
158static void *arm_vmregion_next(struct seq_file *m, void *p, loff_t *pos)
159{
160 struct arm_vmregion_head *h = m->private;
161 return seq_list_next(p, &h->vm_list, pos);
162}
163
164static void arm_vmregion_stop(struct seq_file *m, void *p)
165{
166 struct arm_vmregion_head *h = m->private;
167 spin_unlock_irq(&h->vm_lock);
168}
169
170static const struct seq_operations arm_vmregion_ops = {
171 .start = arm_vmregion_start,
172 .stop = arm_vmregion_stop,
173 .next = arm_vmregion_next,
174 .show = arm_vmregion_show,
175};
176
177static int arm_vmregion_open(struct inode *inode, struct file *file)
178{
179 struct arm_vmregion_head *h = PDE(inode)->data;
180 int ret = seq_open(file, &arm_vmregion_ops);
181 if (!ret) {
182 struct seq_file *m = file->private_data;
183 m->private = h;
184 }
185 return ret;
186}
187
188static const struct file_operations arm_vmregion_fops = {
189 .open = arm_vmregion_open,
190 .read = seq_read,
191 .llseek = seq_lseek,
192 .release = seq_release,
193};
194
195int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
196{
197 proc_create_data(path, S_IRUSR, NULL, &arm_vmregion_fops, h);
198 return 0;
199}
200#else
201int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
202{
203 return 0;
204}
205#endif
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index 15e9f044db9..162be662c08 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -19,11 +19,14 @@ struct arm_vmregion {
19 unsigned long vm_end; 19 unsigned long vm_end;
20 struct page *vm_pages; 20 struct page *vm_pages;
21 int vm_active; 21 int vm_active;
22 const void *caller;
22}; 23};
23 24
24struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t); 25struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *);
25struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); 26struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
26struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); 27struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
27void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); 28void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
28 29
30int arm_vmregion_create_proc(const char *, struct arm_vmregion_head *);
31
29#endif 32#endif
diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile
new file mode 100644
index 00000000000..c2c10841b6b
--- /dev/null
+++ b/arch/arm/net/Makefile
@@ -0,0 +1,3 @@
1# ARM-specific networking code
2
3obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
new file mode 100644
index 00000000000..62135849f48
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.c
@@ -0,0 +1,915 @@
1/*
2 * Just-In-Time compiler for BPF filters on 32bit ARM
3 *
4 * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License.
9 */
10
11#include <linux/bitops.h>
12#include <linux/compiler.h>
13#include <linux/errno.h>
14#include <linux/filter.h>
15#include <linux/moduleloader.h>
16#include <linux/netdevice.h>
17#include <linux/string.h>
18#include <linux/slab.h>
19#include <asm/cacheflush.h>
20#include <asm/hwcap.h>
21
22#include "bpf_jit_32.h"
23
24/*
25 * ABI:
26 *
27 * r0 scratch register
28 * r4 BPF register A
29 * r5 BPF register X
30 * r6 pointer to the skb
31 * r7 skb->data
32 * r8 skb_headlen(skb)
33 */
34
35#define r_scratch ARM_R0
36/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */
37#define r_off ARM_R1
38#define r_A ARM_R4
39#define r_X ARM_R5
40#define r_skb ARM_R6
41#define r_skb_data ARM_R7
42#define r_skb_hl ARM_R8
43
44#define SCRATCH_SP_OFFSET 0
45#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k))
46
47#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1)
48#define SEEN_MEM_WORD(k) (1 << (k))
49#define SEEN_X (1 << BPF_MEMWORDS)
50#define SEEN_CALL (1 << (BPF_MEMWORDS + 1))
51#define SEEN_SKB (1 << (BPF_MEMWORDS + 2))
52#define SEEN_DATA (1 << (BPF_MEMWORDS + 3))
53
54#define FLAG_NEED_X_RESET (1 << 0)
55
56struct jit_ctx {
57 const struct sk_filter *skf;
58 unsigned idx;
59 unsigned prologue_bytes;
60 int ret0_fp_idx;
61 u32 seen;
62 u32 flags;
63 u32 *offsets;
64 u32 *target;
65#if __LINUX_ARM_ARCH__ < 7
66 u16 epilogue_bytes;
67 u16 imm_count;
68 u32 *imms;
69#endif
70};
71
72int bpf_jit_enable __read_mostly;
73
74static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
75{
76 u8 ret;
77 int err;
78
79 err = skb_copy_bits(skb, offset, &ret, 1);
80
81 return (u64)err << 32 | ret;
82}
83
84static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
85{
86 u16 ret;
87 int err;
88
89 err = skb_copy_bits(skb, offset, &ret, 2);
90
91 return (u64)err << 32 | ntohs(ret);
92}
93
94static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
95{
96 u32 ret;
97 int err;
98
99 err = skb_copy_bits(skb, offset, &ret, 4);
100
101 return (u64)err << 32 | ntohl(ret);
102}
103
104/*
105 * Wrapper that handles both OABI and EABI and assures Thumb2 interworking
106 * (where the assembly routines like __aeabi_uidiv could cause problems).
107 */
108static u32 jit_udiv(u32 dividend, u32 divisor)
109{
110 return dividend / divisor;
111}
112
113static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
114{
115 if (ctx->target != NULL)
116 ctx->target[ctx->idx] = inst | (cond << 28);
117
118 ctx->idx++;
119}
120
121/*
122 * Emit an instruction that will be executed unconditionally.
123 */
124static inline void emit(u32 inst, struct jit_ctx *ctx)
125{
126 _emit(ARM_COND_AL, inst, ctx);
127}
128
129static u16 saved_regs(struct jit_ctx *ctx)
130{
131 u16 ret = 0;
132
133 if ((ctx->skf->len > 1) ||
134 (ctx->skf->insns[0].code == BPF_S_RET_A))
135 ret |= 1 << r_A;
136
137#ifdef CONFIG_FRAME_POINTER
138 ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC);
139#else
140 if (ctx->seen & SEEN_CALL)
141 ret |= 1 << ARM_LR;
142#endif
143 if (ctx->seen & (SEEN_DATA | SEEN_SKB))
144 ret |= 1 << r_skb;
145 if (ctx->seen & SEEN_DATA)
146 ret |= (1 << r_skb_data) | (1 << r_skb_hl);
147 if (ctx->seen & SEEN_X)
148 ret |= 1 << r_X;
149
150 return ret;
151}
152
153static inline int mem_words_used(struct jit_ctx *ctx)
154{
155 /* yes, we do waste some stack space IF there are "holes" in the set" */
156 return fls(ctx->seen & SEEN_MEM);
157}
158
159static inline bool is_load_to_a(u16 inst)
160{
161 switch (inst) {
162 case BPF_S_LD_W_LEN:
163 case BPF_S_LD_W_ABS:
164 case BPF_S_LD_H_ABS:
165 case BPF_S_LD_B_ABS:
166 case BPF_S_ANC_CPU:
167 case BPF_S_ANC_IFINDEX:
168 case BPF_S_ANC_MARK:
169 case BPF_S_ANC_PROTOCOL:
170 case BPF_S_ANC_RXHASH:
171 case BPF_S_ANC_QUEUE:
172 return true;
173 default:
174 return false;
175 }
176}
177
178static void build_prologue(struct jit_ctx *ctx)
179{
180 u16 reg_set = saved_regs(ctx);
181 u16 first_inst = ctx->skf->insns[0].code;
182 u16 off;
183
184#ifdef CONFIG_FRAME_POINTER
185 emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx);
186 emit(ARM_PUSH(reg_set), ctx);
187 emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx);
188#else
189 if (reg_set)
190 emit(ARM_PUSH(reg_set), ctx);
191#endif
192
193 if (ctx->seen & (SEEN_DATA | SEEN_SKB))
194 emit(ARM_MOV_R(r_skb, ARM_R0), ctx);
195
196 if (ctx->seen & SEEN_DATA) {
197 off = offsetof(struct sk_buff, data);
198 emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx);
199 /* headlen = len - data_len */
200 off = offsetof(struct sk_buff, len);
201 emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx);
202 off = offsetof(struct sk_buff, data_len);
203 emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
204 emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx);
205 }
206
207 if (ctx->flags & FLAG_NEED_X_RESET)
208 emit(ARM_MOV_I(r_X, 0), ctx);
209
210 /* do not leak kernel data to userspace */
211 if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst)))
212 emit(ARM_MOV_I(r_A, 0), ctx);
213
214 /* stack space for the BPF_MEM words */
215 if (ctx->seen & SEEN_MEM)
216 emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
217}
218
219static void build_epilogue(struct jit_ctx *ctx)
220{
221 u16 reg_set = saved_regs(ctx);
222
223 if (ctx->seen & SEEN_MEM)
224 emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
225
226 reg_set &= ~(1 << ARM_LR);
227
228#ifdef CONFIG_FRAME_POINTER
229 /* the first instruction of the prologue was: mov ip, sp */
230 reg_set &= ~(1 << ARM_IP);
231 reg_set |= (1 << ARM_SP);
232 emit(ARM_LDM(ARM_SP, reg_set), ctx);
233#else
234 if (reg_set) {
235 if (ctx->seen & SEEN_CALL)
236 reg_set |= 1 << ARM_PC;
237 emit(ARM_POP(reg_set), ctx);
238 }
239
240 if (!(ctx->seen & SEEN_CALL))
241 emit(ARM_BX(ARM_LR), ctx);
242#endif
243}
244
245static int16_t imm8m(u32 x)
246{
247 u32 rot;
248
249 for (rot = 0; rot < 16; rot++)
250 if ((x & ~ror32(0xff, 2 * rot)) == 0)
251 return rol32(x, 2 * rot) | (rot << 8);
252
253 return -1;
254}
255
256#if __LINUX_ARM_ARCH__ < 7
257
258static u16 imm_offset(u32 k, struct jit_ctx *ctx)
259{
260 unsigned i = 0, offset;
261 u16 imm;
262
263 /* on the "fake" run we just count them (duplicates included) */
264 if (ctx->target == NULL) {
265 ctx->imm_count++;
266 return 0;
267 }
268
269 while ((i < ctx->imm_count) && ctx->imms[i]) {
270 if (ctx->imms[i] == k)
271 break;
272 i++;
273 }
274
275 if (ctx->imms[i] == 0)
276 ctx->imms[i] = k;
277
278 /* constants go just after the epilogue */
279 offset = ctx->offsets[ctx->skf->len];
280 offset += ctx->prologue_bytes;
281 offset += ctx->epilogue_bytes;
282 offset += i * 4;
283
284 ctx->target[offset / 4] = k;
285
286 /* PC in ARM mode == address of the instruction + 8 */
287 imm = offset - (8 + ctx->idx * 4);
288
289 return imm;
290}
291
292#endif /* __LINUX_ARM_ARCH__ */
293
294/*
295 * Move an immediate that's not an imm8m to a core register.
296 */
297static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx)
298{
299#if __LINUX_ARM_ARCH__ < 7
300 emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx);
301#else
302 emit(ARM_MOVW(rd, val & 0xffff), ctx);
303 if (val > 0xffff)
304 emit(ARM_MOVT(rd, val >> 16), ctx);
305#endif
306}
307
308static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx)
309{
310 int imm12 = imm8m(val);
311
312 if (imm12 >= 0)
313 emit(ARM_MOV_I(rd, imm12), ctx);
314 else
315 emit_mov_i_no8m(rd, val, ctx);
316}
317
318#if __LINUX_ARM_ARCH__ < 6
319
320static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
321{
322 _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx);
323 _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
324 _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx);
325 _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx);
326 _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx);
327 _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx);
328 _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx);
329 _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx);
330}
331
332static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
333{
334 _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
335 _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx);
336 _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx);
337}
338
339static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx)
340{
341 emit(ARM_LSL_R(ARM_R1, r_src, 8), ctx);
342 emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSL, 8), ctx);
343 emit(ARM_LSL_I(r_dst, r_dst, 8), ctx);
344 emit(ARM_LSL_R(r_dst, r_dst, 8), ctx);
345}
346
347#else /* ARMv6+ */
348
349static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
350{
351 _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx);
352#ifdef __LITTLE_ENDIAN
353 _emit(cond, ARM_REV(r_res, r_res), ctx);
354#endif
355}
356
357static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
358{
359 _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx);
360#ifdef __LITTLE_ENDIAN
361 _emit(cond, ARM_REV16(r_res, r_res), ctx);
362#endif
363}
364
365static inline void emit_swap16(u8 r_dst __maybe_unused,
366 u8 r_src __maybe_unused,
367 struct jit_ctx *ctx __maybe_unused)
368{
369#ifdef __LITTLE_ENDIAN
370 emit(ARM_REV16(r_dst, r_src), ctx);
371#endif
372}
373
374#endif /* __LINUX_ARM_ARCH__ < 6 */
375
376
377/* Compute the immediate value for a PC-relative branch. */
378static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx)
379{
380 u32 imm;
381
382 if (ctx->target == NULL)
383 return 0;
384 /*
385 * BPF allows only forward jumps and the offset of the target is
386 * still the one computed during the first pass.
387 */
388 imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8);
389
390 return imm >> 2;
391}
392
393#define OP_IMM3(op, r1, r2, imm_val, ctx) \
394 do { \
395 imm12 = imm8m(imm_val); \
396 if (imm12 < 0) { \
397 emit_mov_i_no8m(r_scratch, imm_val, ctx); \
398 emit(op ## _R((r1), (r2), r_scratch), ctx); \
399 } else { \
400 emit(op ## _I((r1), (r2), imm12), ctx); \
401 } \
402 } while (0)
403
404static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx)
405{
406 if (ctx->ret0_fp_idx >= 0) {
407 _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx);
408 /* NOP to keep the size constant between passes */
409 emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx);
410 } else {
411 _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx);
412 _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx);
413 }
414}
415
416static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
417{
418#if __LINUX_ARM_ARCH__ < 5
419 emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx);
420
421 if (elf_hwcap & HWCAP_THUMB)
422 emit(ARM_BX(tgt_reg), ctx);
423 else
424 emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx);
425#else
426 emit(ARM_BLX_R(tgt_reg), ctx);
427#endif
428}
429
430static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
431{
432#if __LINUX_ARM_ARCH__ == 7
433 if (elf_hwcap & HWCAP_IDIVA) {
434 emit(ARM_UDIV(rd, rm, rn), ctx);
435 return;
436 }
437#endif
438 if (rm != ARM_R0)
439 emit(ARM_MOV_R(ARM_R0, rm), ctx);
440 if (rn != ARM_R1)
441 emit(ARM_MOV_R(ARM_R1, rn), ctx);
442
443 ctx->seen |= SEEN_CALL;
444 emit_mov_i(ARM_R3, (u32)jit_udiv, ctx);
445 emit_blx_r(ARM_R3, ctx);
446
447 if (rd != ARM_R0)
448 emit(ARM_MOV_R(rd, ARM_R0), ctx);
449}
450
451static inline void update_on_xread(struct jit_ctx *ctx)
452{
453 if (!(ctx->seen & SEEN_X))
454 ctx->flags |= FLAG_NEED_X_RESET;
455
456 ctx->seen |= SEEN_X;
457}
458
459static int build_body(struct jit_ctx *ctx)
460{
461 void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
462 const struct sk_filter *prog = ctx->skf;
463 const struct sock_filter *inst;
464 unsigned i, load_order, off, condt;
465 int imm12;
466 u32 k;
467
468 for (i = 0; i < prog->len; i++) {
469 inst = &(prog->insns[i]);
470 /* K as an immediate value operand */
471 k = inst->k;
472
473 /* compute offsets only in the fake pass */
474 if (ctx->target == NULL)
475 ctx->offsets[i] = ctx->idx * 4;
476
477 switch (inst->code) {
478 case BPF_S_LD_IMM:
479 emit_mov_i(r_A, k, ctx);
480 break;
481 case BPF_S_LD_W_LEN:
482 ctx->seen |= SEEN_SKB;
483 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
484 emit(ARM_LDR_I(r_A, r_skb,
485 offsetof(struct sk_buff, len)), ctx);
486 break;
487 case BPF_S_LD_MEM:
488 /* A = scratch[k] */
489 ctx->seen |= SEEN_MEM_WORD(k);
490 emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
491 break;
492 case BPF_S_LD_W_ABS:
493 load_order = 2;
494 goto load;
495 case BPF_S_LD_H_ABS:
496 load_order = 1;
497 goto load;
498 case BPF_S_LD_B_ABS:
499 load_order = 0;
500load:
501 /* the interpreter will deal with the negative K */
502 if ((int)k < 0)
503 return -ENOTSUPP;
504 emit_mov_i(r_off, k, ctx);
505load_common:
506 ctx->seen |= SEEN_DATA | SEEN_CALL;
507
508 if (load_order > 0) {
509 emit(ARM_SUB_I(r_scratch, r_skb_hl,
510 1 << load_order), ctx);
511 emit(ARM_CMP_R(r_scratch, r_off), ctx);
512 condt = ARM_COND_HS;
513 } else {
514 emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
515 condt = ARM_COND_HI;
516 }
517
518 _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
519 ctx);
520
521 if (load_order == 0)
522 _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0),
523 ctx);
524 else if (load_order == 1)
525 emit_load_be16(condt, r_A, r_scratch, ctx);
526 else if (load_order == 2)
527 emit_load_be32(condt, r_A, r_scratch, ctx);
528
529 _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx);
530
531 /* the slowpath */
532 emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx);
533 emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
534 /* the offset is already in R1 */
535 emit_blx_r(ARM_R3, ctx);
536 /* check the result of skb_copy_bits */
537 emit(ARM_CMP_I(ARM_R1, 0), ctx);
538 emit_err_ret(ARM_COND_NE, ctx);
539 emit(ARM_MOV_R(r_A, ARM_R0), ctx);
540 break;
541 case BPF_S_LD_W_IND:
542 load_order = 2;
543 goto load_ind;
544 case BPF_S_LD_H_IND:
545 load_order = 1;
546 goto load_ind;
547 case BPF_S_LD_B_IND:
548 load_order = 0;
549load_ind:
550 OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
551 goto load_common;
552 case BPF_S_LDX_IMM:
553 ctx->seen |= SEEN_X;
554 emit_mov_i(r_X, k, ctx);
555 break;
556 case BPF_S_LDX_W_LEN:
557 ctx->seen |= SEEN_X | SEEN_SKB;
558 emit(ARM_LDR_I(r_X, r_skb,
559 offsetof(struct sk_buff, len)), ctx);
560 break;
561 case BPF_S_LDX_MEM:
562 ctx->seen |= SEEN_X | SEEN_MEM_WORD(k);
563 emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
564 break;
565 case BPF_S_LDX_B_MSH:
566 /* x = ((*(frame + k)) & 0xf) << 2; */
567 ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
568 /* the interpreter should deal with the negative K */
569 if (k < 0)
570 return -1;
571 /* offset in r1: we might have to take the slow path */
572 emit_mov_i(r_off, k, ctx);
573 emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
574
575 /* load in r0: common with the slowpath */
576 _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data,
577 ARM_R1), ctx);
578 /*
579 * emit_mov_i() might generate one or two instructions,
580 * the same holds for emit_blx_r()
581 */
582 _emit(ARM_COND_HI, ARM_B(b_imm(i + 1, ctx) - 2), ctx);
583
584 emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
585 /* r_off is r1 */
586 emit_mov_i(ARM_R3, (u32)jit_get_skb_b, ctx);
587 emit_blx_r(ARM_R3, ctx);
588 /* check the return value of skb_copy_bits */
589 emit(ARM_CMP_I(ARM_R1, 0), ctx);
590 emit_err_ret(ARM_COND_NE, ctx);
591
592 emit(ARM_AND_I(r_X, ARM_R0, 0x00f), ctx);
593 emit(ARM_LSL_I(r_X, r_X, 2), ctx);
594 break;
595 case BPF_S_ST:
596 ctx->seen |= SEEN_MEM_WORD(k);
597 emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
598 break;
599 case BPF_S_STX:
600 update_on_xread(ctx);
601 ctx->seen |= SEEN_MEM_WORD(k);
602 emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
603 break;
604 case BPF_S_ALU_ADD_K:
605 /* A += K */
606 OP_IMM3(ARM_ADD, r_A, r_A, k, ctx);
607 break;
608 case BPF_S_ALU_ADD_X:
609 update_on_xread(ctx);
610 emit(ARM_ADD_R(r_A, r_A, r_X), ctx);
611 break;
612 case BPF_S_ALU_SUB_K:
613 /* A -= K */
614 OP_IMM3(ARM_SUB, r_A, r_A, k, ctx);
615 break;
616 case BPF_S_ALU_SUB_X:
617 update_on_xread(ctx);
618 emit(ARM_SUB_R(r_A, r_A, r_X), ctx);
619 break;
620 case BPF_S_ALU_MUL_K:
621 /* A *= K */
622 emit_mov_i(r_scratch, k, ctx);
623 emit(ARM_MUL(r_A, r_A, r_scratch), ctx);
624 break;
625 case BPF_S_ALU_MUL_X:
626 update_on_xread(ctx);
627 emit(ARM_MUL(r_A, r_A, r_X), ctx);
628 break;
629 case BPF_S_ALU_DIV_K:
630 /* current k == reciprocal_value(userspace k) */
631 emit_mov_i(r_scratch, k, ctx);
632 /* A = top 32 bits of the product */
633 emit(ARM_UMULL(r_scratch, r_A, r_A, r_scratch), ctx);
634 break;
635 case BPF_S_ALU_DIV_X:
636 update_on_xread(ctx);
637 emit(ARM_CMP_I(r_X, 0), ctx);
638 emit_err_ret(ARM_COND_EQ, ctx);
639 emit_udiv(r_A, r_A, r_X, ctx);
640 break;
641 case BPF_S_ALU_OR_K:
642 /* A |= K */
643 OP_IMM3(ARM_ORR, r_A, r_A, k, ctx);
644 break;
645 case BPF_S_ALU_OR_X:
646 update_on_xread(ctx);
647 emit(ARM_ORR_R(r_A, r_A, r_X), ctx);
648 break;
649 case BPF_S_ALU_AND_K:
650 /* A &= K */
651 OP_IMM3(ARM_AND, r_A, r_A, k, ctx);
652 break;
653 case BPF_S_ALU_AND_X:
654 update_on_xread(ctx);
655 emit(ARM_AND_R(r_A, r_A, r_X), ctx);
656 break;
657 case BPF_S_ALU_LSH_K:
658 if (unlikely(k > 31))
659 return -1;
660 emit(ARM_LSL_I(r_A, r_A, k), ctx);
661 break;
662 case BPF_S_ALU_LSH_X:
663 update_on_xread(ctx);
664 emit(ARM_LSL_R(r_A, r_A, r_X), ctx);
665 break;
666 case BPF_S_ALU_RSH_K:
667 if (unlikely(k > 31))
668 return -1;
669 emit(ARM_LSR_I(r_A, r_A, k), ctx);
670 break;
671 case BPF_S_ALU_RSH_X:
672 update_on_xread(ctx);
673 emit(ARM_LSR_R(r_A, r_A, r_X), ctx);
674 break;
675 case BPF_S_ALU_NEG:
676 /* A = -A */
677 emit(ARM_RSB_I(r_A, r_A, 0), ctx);
678 break;
679 case BPF_S_JMP_JA:
680 /* pc += K */
681 emit(ARM_B(b_imm(i + k + 1, ctx)), ctx);
682 break;
683 case BPF_S_JMP_JEQ_K:
684 /* pc += (A == K) ? pc->jt : pc->jf */
685 condt = ARM_COND_EQ;
686 goto cmp_imm;
687 case BPF_S_JMP_JGT_K:
688 /* pc += (A > K) ? pc->jt : pc->jf */
689 condt = ARM_COND_HI;
690 goto cmp_imm;
691 case BPF_S_JMP_JGE_K:
692 /* pc += (A >= K) ? pc->jt : pc->jf */
693 condt = ARM_COND_HS;
694cmp_imm:
695 imm12 = imm8m(k);
696 if (imm12 < 0) {
697 emit_mov_i_no8m(r_scratch, k, ctx);
698 emit(ARM_CMP_R(r_A, r_scratch), ctx);
699 } else {
700 emit(ARM_CMP_I(r_A, imm12), ctx);
701 }
702cond_jump:
703 if (inst->jt)
704 _emit(condt, ARM_B(b_imm(i + inst->jt + 1,
705 ctx)), ctx);
706 if (inst->jf)
707 _emit(condt ^ 1, ARM_B(b_imm(i + inst->jf + 1,
708 ctx)), ctx);
709 break;
710 case BPF_S_JMP_JEQ_X:
711 /* pc += (A == X) ? pc->jt : pc->jf */
712 condt = ARM_COND_EQ;
713 goto cmp_x;
714 case BPF_S_JMP_JGT_X:
715 /* pc += (A > X) ? pc->jt : pc->jf */
716 condt = ARM_COND_HI;
717 goto cmp_x;
718 case BPF_S_JMP_JGE_X:
719 /* pc += (A >= X) ? pc->jt : pc->jf */
720 condt = ARM_COND_CS;
721cmp_x:
722 update_on_xread(ctx);
723 emit(ARM_CMP_R(r_A, r_X), ctx);
724 goto cond_jump;
725 case BPF_S_JMP_JSET_K:
726 /* pc += (A & K) ? pc->jt : pc->jf */
727 condt = ARM_COND_NE;
728 /* not set iff all zeroes iff Z==1 iff EQ */
729
730 imm12 = imm8m(k);
731 if (imm12 < 0) {
732 emit_mov_i_no8m(r_scratch, k, ctx);
733 emit(ARM_TST_R(r_A, r_scratch), ctx);
734 } else {
735 emit(ARM_TST_I(r_A, imm12), ctx);
736 }
737 goto cond_jump;
738 case BPF_S_JMP_JSET_X:
739 /* pc += (A & X) ? pc->jt : pc->jf */
740 update_on_xread(ctx);
741 condt = ARM_COND_NE;
742 emit(ARM_TST_R(r_A, r_X), ctx);
743 goto cond_jump;
744 case BPF_S_RET_A:
745 emit(ARM_MOV_R(ARM_R0, r_A), ctx);
746 goto b_epilogue;
747 case BPF_S_RET_K:
748 if ((k == 0) && (ctx->ret0_fp_idx < 0))
749 ctx->ret0_fp_idx = i;
750 emit_mov_i(ARM_R0, k, ctx);
751b_epilogue:
752 if (i != ctx->skf->len - 1)
753 emit(ARM_B(b_imm(prog->len, ctx)), ctx);
754 break;
755 case BPF_S_MISC_TAX:
756 /* X = A */
757 ctx->seen |= SEEN_X;
758 emit(ARM_MOV_R(r_X, r_A), ctx);
759 break;
760 case BPF_S_MISC_TXA:
761 /* A = X */
762 update_on_xread(ctx);
763 emit(ARM_MOV_R(r_A, r_X), ctx);
764 break;
765 case BPF_S_ANC_PROTOCOL:
766 /* A = ntohs(skb->protocol) */
767 ctx->seen |= SEEN_SKB;
768 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
769 protocol) != 2);
770 off = offsetof(struct sk_buff, protocol);
771 emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx);
772 emit_swap16(r_A, r_scratch, ctx);
773 break;
774 case BPF_S_ANC_CPU:
775 /* r_scratch = current_thread_info() */
776 OP_IMM3(ARM_BIC, r_scratch, ARM_SP, THREAD_SIZE - 1, ctx);
777 /* A = current_thread_info()->cpu */
778 BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4);
779 off = offsetof(struct thread_info, cpu);
780 emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
781 break;
782 case BPF_S_ANC_IFINDEX:
783 /* A = skb->dev->ifindex */
784 ctx->seen |= SEEN_SKB;
785 off = offsetof(struct sk_buff, dev);
786 emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
787
788 emit(ARM_CMP_I(r_scratch, 0), ctx);
789 emit_err_ret(ARM_COND_EQ, ctx);
790
791 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
792 ifindex) != 4);
793 off = offsetof(struct net_device, ifindex);
794 emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
795 break;
796 case BPF_S_ANC_MARK:
797 ctx->seen |= SEEN_SKB;
798 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
799 off = offsetof(struct sk_buff, mark);
800 emit(ARM_LDR_I(r_A, r_skb, off), ctx);
801 break;
802 case BPF_S_ANC_RXHASH:
803 ctx->seen |= SEEN_SKB;
804 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
805 off = offsetof(struct sk_buff, rxhash);
806 emit(ARM_LDR_I(r_A, r_skb, off), ctx);
807 break;
808 case BPF_S_ANC_QUEUE:
809 ctx->seen |= SEEN_SKB;
810 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
811 queue_mapping) != 2);
812 BUILD_BUG_ON(offsetof(struct sk_buff,
813 queue_mapping) > 0xff);
814 off = offsetof(struct sk_buff, queue_mapping);
815 emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
816 break;
817 default:
818 return -1;
819 }
820 }
821
822 /* compute offsets only during the first pass */
823 if (ctx->target == NULL)
824 ctx->offsets[i] = ctx->idx * 4;
825
826 return 0;
827}
828
829
830void bpf_jit_compile(struct sk_filter *fp)
831{
832 struct jit_ctx ctx;
833 unsigned tmp_idx;
834 unsigned alloc_size;
835
836 if (!bpf_jit_enable)
837 return;
838
839 memset(&ctx, 0, sizeof(ctx));
840 ctx.skf = fp;
841 ctx.ret0_fp_idx = -1;
842
843 ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1));
844 if (ctx.offsets == NULL)
845 return;
846
847 /* fake pass to fill in the ctx->seen */
848 if (unlikely(build_body(&ctx)))
849 goto out;
850
851 tmp_idx = ctx.idx;
852 build_prologue(&ctx);
853 ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4;
854
855#if __LINUX_ARM_ARCH__ < 7
856 tmp_idx = ctx.idx;
857 build_epilogue(&ctx);
858 ctx.epilogue_bytes = (ctx.idx - tmp_idx) * 4;
859
860 ctx.idx += ctx.imm_count;
861 if (ctx.imm_count) {
862 ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count);
863 if (ctx.imms == NULL)
864 goto out;
865 }
866#else
867 /* there's nothing after the epilogue on ARMv7 */
868 build_epilogue(&ctx);
869#endif
870
871 alloc_size = 4 * ctx.idx;
872 ctx.target = module_alloc(max(sizeof(struct work_struct),
873 alloc_size));
874 if (unlikely(ctx.target == NULL))
875 goto out;
876
877 ctx.idx = 0;
878 build_prologue(&ctx);
879 build_body(&ctx);
880 build_epilogue(&ctx);
881
882 flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
883
884#if __LINUX_ARM_ARCH__ < 7
885 if (ctx.imm_count)
886 kfree(ctx.imms);
887#endif
888
889 if (bpf_jit_enable > 1)
890 print_hex_dump(KERN_INFO, "BPF JIT code: ",
891 DUMP_PREFIX_ADDRESS, 16, 4, ctx.target,
892 alloc_size, false);
893
894 fp->bpf_func = (void *)ctx.target;
895out:
896 kfree(ctx.offsets);
897 return;
898}
899
900static void bpf_jit_free_worker(struct work_struct *work)
901{
902 module_free(NULL, work);
903}
904
905void bpf_jit_free(struct sk_filter *fp)
906{
907 struct work_struct *work;
908
909 if (fp->bpf_func != sk_run_filter) {
910 work = (struct work_struct *)fp->bpf_func;
911
912 INIT_WORK(work, bpf_jit_free_worker);
913 schedule_work(work);
914 }
915}
diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h
new file mode 100644
index 00000000000..99ae5e3f46d
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.h
@@ -0,0 +1,190 @@
1/*
2 * Just-In-Time compiler for BPF filters on 32bit ARM
3 *
4 * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License.
9 */
10
11#ifndef PFILTER_OPCODES_ARM_H
12#define PFILTER_OPCODES_ARM_H
13
14#define ARM_R0 0
15#define ARM_R1 1
16#define ARM_R2 2
17#define ARM_R3 3
18#define ARM_R4 4
19#define ARM_R5 5
20#define ARM_R6 6
21#define ARM_R7 7
22#define ARM_R8 8
23#define ARM_R9 9
24#define ARM_R10 10
25#define ARM_FP 11
26#define ARM_IP 12
27#define ARM_SP 13
28#define ARM_LR 14
29#define ARM_PC 15
30
31#define ARM_COND_EQ 0x0
32#define ARM_COND_NE 0x1
33#define ARM_COND_CS 0x2
34#define ARM_COND_HS ARM_COND_CS
35#define ARM_COND_CC 0x3
36#define ARM_COND_LO ARM_COND_CC
37#define ARM_COND_MI 0x4
38#define ARM_COND_PL 0x5
39#define ARM_COND_VS 0x6
40#define ARM_COND_VC 0x7
41#define ARM_COND_HI 0x8
42#define ARM_COND_LS 0x9
43#define ARM_COND_GE 0xa
44#define ARM_COND_LT 0xb
45#define ARM_COND_GT 0xc
46#define ARM_COND_LE 0xd
47#define ARM_COND_AL 0xe
48
49/* register shift types */
50#define SRTYPE_LSL 0
51#define SRTYPE_LSR 1
52#define SRTYPE_ASR 2
53#define SRTYPE_ROR 3
54
55#define ARM_INST_ADD_R 0x00800000
56#define ARM_INST_ADD_I 0x02800000
57
58#define ARM_INST_AND_R 0x00000000
59#define ARM_INST_AND_I 0x02000000
60
61#define ARM_INST_BIC_R 0x01c00000
62#define ARM_INST_BIC_I 0x03c00000
63
64#define ARM_INST_B 0x0a000000
65#define ARM_INST_BX 0x012FFF10
66#define ARM_INST_BLX_R 0x012fff30
67
68#define ARM_INST_CMP_R 0x01500000
69#define ARM_INST_CMP_I 0x03500000
70
71#define ARM_INST_LDRB_I 0x05d00000
72#define ARM_INST_LDRB_R 0x07d00000
73#define ARM_INST_LDRH_I 0x01d000b0
74#define ARM_INST_LDR_I 0x05900000
75
76#define ARM_INST_LDM 0x08900000
77
78#define ARM_INST_LSL_I 0x01a00000
79#define ARM_INST_LSL_R 0x01a00010
80
81#define ARM_INST_LSR_I 0x01a00020
82#define ARM_INST_LSR_R 0x01a00030
83
84#define ARM_INST_MOV_R 0x01a00000
85#define ARM_INST_MOV_I 0x03a00000
86#define ARM_INST_MOVW 0x03000000
87#define ARM_INST_MOVT 0x03400000
88
89#define ARM_INST_MUL 0x00000090
90
91#define ARM_INST_POP 0x08bd0000
92#define ARM_INST_PUSH 0x092d0000
93
94#define ARM_INST_ORR_R 0x01800000
95#define ARM_INST_ORR_I 0x03800000
96
97#define ARM_INST_REV 0x06bf0f30
98#define ARM_INST_REV16 0x06bf0fb0
99
100#define ARM_INST_RSB_I 0x02600000
101
102#define ARM_INST_SUB_R 0x00400000
103#define ARM_INST_SUB_I 0x02400000
104
105#define ARM_INST_STR_I 0x05800000
106
107#define ARM_INST_TST_R 0x01100000
108#define ARM_INST_TST_I 0x03100000
109
110#define ARM_INST_UDIV 0x0730f010
111
112#define ARM_INST_UMULL 0x00800090
113
114/* register */
115#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm))
116/* immediate */
117#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm))
118
119#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm)
120#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm)
121
122#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm)
123#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm)
124
125#define ARM_BIC_R(rd, rn, rm) _AL3_R(ARM_INST_BIC, rd, rn, rm)
126#define ARM_BIC_I(rd, rn, imm) _AL3_I(ARM_INST_BIC, rd, rn, imm)
127
128#define ARM_B(imm24) (ARM_INST_B | ((imm24) & 0xffffff))
129#define ARM_BX(rm) (ARM_INST_BX | (rm))
130#define ARM_BLX_R(rm) (ARM_INST_BLX_R | (rm))
131
132#define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm)
133#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm)
134
135#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
136 | (off))
137#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \
138 | (off))
139#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \
140 | (rm))
141#define ARM_LDRH_I(rt, rn, off) (ARM_INST_LDRH_I | (rt) << 12 | (rn) << 16 \
142 | (((off) & 0xf0) << 4) | ((off) & 0xf))
143
144#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs))
145
146#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8)
147#define ARM_LSL_I(rd, rn, imm) (_AL3_I(ARM_INST_LSL, rd, 0, rn) | (imm) << 7)
148
149#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8)
150#define ARM_LSR_I(rd, rn, imm) (_AL3_I(ARM_INST_LSR, rd, 0, rn) | (imm) << 7)
151
152#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm)
153#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm)
154
155#define ARM_MOVW(rd, imm) \
156 (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
157
158#define ARM_MOVT(rd, imm) \
159 (ARM_INST_MOVT | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
160
161#define ARM_MUL(rd, rm, rn) (ARM_INST_MUL | (rd) << 16 | (rm) << 8 | (rn))
162
163#define ARM_POP(regs) (ARM_INST_POP | (regs))
164#define ARM_PUSH(regs) (ARM_INST_PUSH | (regs))
165
166#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm)
167#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm)
168#define ARM_ORR_S(rd, rn, rm, type, rs) \
169 (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7)
170
171#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm))
172#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm))
173
174#define ARM_RSB_I(rd, rn, imm) _AL3_I(ARM_INST_RSB, rd, rn, imm)
175
176#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm)
177#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm)
178
179#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \
180 | (off))
181
182#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm)
183#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm)
184
185#define ARM_UDIV(rd, rn, rm) (ARM_INST_UDIV | (rd) << 16 | (rn) | (rm) << 8)
186
187#define ARM_UMULL(rd_lo, rd_hi, rn, rm) (ARM_INST_UMULL | (rd_hi) << 16 \
188 | (rd_lo) << 12 | (rm) << 8 | rn)
189
190#endif /* PFILTER_OPCODES_ARM_H */
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index bca4914b4b9..4c48c8b60b5 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -23,7 +23,6 @@ config HAS_MTU
23config NOMADIK_MTU_SCHED_CLOCK 23config NOMADIK_MTU_SCHED_CLOCK
24 bool 24 bool
25 depends on HAS_MTU 25 depends on HAS_MTU
26 select HAVE_SCHED_CLOCK
27 help 26 help
28 Use the Multi Timer Unit as the sched_clock. 27 Use the Multi Timer Unit as the sched_clock.
29 28
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
index 52353beb369..043f7b02a9e 100644
--- a/arch/arm/plat-versatile/Kconfig
+++ b/arch/arm/plat-versatile/Kconfig
@@ -11,7 +11,6 @@ config PLAT_VERSATILE_LEDS
11 depends on ARCH_REALVIEW || ARCH_VERSATILE 11 depends on ARCH_REALVIEW || ARCH_VERSATILE
12 12
13config PLAT_VERSATILE_SCHED_CLOCK 13config PLAT_VERSATILE_SCHED_CLOCK
14 def_bool y if !ARCH_INTEGRATOR_AP 14 def_bool y
15 select HAVE_SCHED_CLOCK
16 15
17endif 16endif