diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-29 19:53:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-29 19:53:48 -0400 |
commit | 12679a2d7e3bfbdc7586e3e86d1ca90c46659363 (patch) | |
tree | d9c00f2e599d1c3e04a349229a6a19906d01f99e /arch/arm | |
parent | 1c036588772d01655d851f75dffc27c971e072e2 (diff) | |
parent | b0df89868006517417251e02cc4ce5d4b0165885 (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')
144 files changed, 2192 insertions, 510 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5098564d5879..242f3a33d741 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 | |||
52 | config SYS_SUPPORTS_APM_EMULATION | 54 | config SYS_SUPPORTS_APM_EMULATION |
53 | bool | 55 | bool |
54 | 56 | ||
55 | config HAVE_SCHED_CLOCK | ||
56 | bool | ||
57 | |||
58 | config GENERIC_GPIO | 57 | config 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 | |||
1115 | config PLAT_IOP | 1106 | config PLAT_IOP |
1116 | bool | 1107 | bool |
1117 | select GENERIC_CLOCKEVENTS | 1108 | select GENERIC_CLOCKEVENTS |
1118 | select HAVE_SCHED_CLOCK | ||
1119 | 1109 | ||
1120 | config PLAT_ORION | 1110 | config 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 | ||
1126 | config PLAT_PXA | 1115 | config PLAT_PXA |
1127 | bool | 1116 | bool |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 66ca8014ff3e..85348a09d655 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 | |||
295 | endchoice | 311 | endchoice |
296 | 312 | ||
297 | config EARLY_PRINTK | 313 | config EARLY_PRINTK |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index dcb088e868fe..047a20780fc1 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. |
255 | core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ | 255 | core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ |
256 | core-y += arch/arm/net/ | ||
256 | core-y += $(machdirs) $(platdirs) | 257 | core-y += $(machdirs) $(platdirs) |
257 | 258 | ||
258 | drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ | 259 | drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ |
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index e0936a148516..d0d441c429ae 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore | |||
@@ -1,8 +1,10 @@ | |||
1 | ashldi3.S | ||
1 | font.c | 2 | font.c |
2 | lib1funcs.S | 3 | lib1funcs.S |
3 | piggy.gzip | 4 | piggy.gzip |
4 | piggy.lzo | 5 | piggy.lzo |
5 | piggy.lzma | 6 | piggy.lzma |
7 | piggy.xzkern | ||
6 | vmlinux | 8 | vmlinux |
7 | vmlinux.lds | 9 | vmlinux.lds |
8 | 10 | ||
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index cf0a64ce4b83..bb267562e7ed 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)/ | |||
92 | suffix_$(CONFIG_KERNEL_GZIP) = gzip | 92 | suffix_$(CONFIG_KERNEL_GZIP) = gzip |
93 | suffix_$(CONFIG_KERNEL_LZO) = lzo | 93 | suffix_$(CONFIG_KERNEL_LZO) = lzo |
94 | suffix_$(CONFIG_KERNEL_LZMA) = lzma | 94 | suffix_$(CONFIG_KERNEL_LZMA) = lzma |
95 | suffix_$(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 | ||
113 | targets := vmlinux vmlinux.lds \ | 114 | targets := 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 |
118 | extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs) | 120 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ |
121 | lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) | ||
119 | 122 | ||
120 | ifeq ($(CONFIG_FUNCTION_TRACER),y) | 123 | ifeq ($(CONFIG_FUNCTION_TRACER),y) |
121 | ORIG_CFLAGS := $(KBUILD_CFLAGS) | 124 | ORIG_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 | ||
158 | ashldi3 = $(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 \ | |||
172 | fi | 181 | fi |
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 07be5a2f8302..f41b38cafce8 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 | |||
47 | int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) | 53 | int 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 000000000000..5703f300d027 --- /dev/null +++ b/arch/arm/boot/compressed/piggy.xzkern.S | |||
@@ -0,0 +1,6 @@ | |||
1 | .section .piggydata,#alloc | ||
2 | .globl input_data | ||
3 | input_data: | ||
4 | .incbin "arch/arm/boot/compressed/piggy.xzkern" | ||
5 | .globl input_data_end | ||
6 | input_data_end: | ||
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index f0783be17352..aa5269984187 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 1103f62a1964..a8314c3ee84d 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig | |||
@@ -57,18 +57,24 @@ CONFIG_NETDEVICES=y | |||
57 | CONFIG_NET_ETHERNET=y | 57 | CONFIG_NET_ETHERNET=y |
58 | CONFIG_NET_PCI=y | 58 | CONFIG_NET_PCI=y |
59 | CONFIG_E100=y | 59 | CONFIG_E100=y |
60 | CONFIG_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 |
62 | CONFIG_SERIAL_AMBA_PL010=y | 63 | CONFIG_SERIAL_AMBA_PL010=y |
63 | CONFIG_SERIAL_AMBA_PL010_CONSOLE=y | 64 | CONFIG_SERIAL_AMBA_PL010_CONSOLE=y |
64 | CONFIG_FB=y | 65 | CONFIG_FB=y |
65 | CONFIG_FB_MODE_HELPERS=y | 66 | CONFIG_FB_MODE_HELPERS=y |
67 | CONFIG_FB_ARMCLCD=y | ||
66 | CONFIG_FB_MATROX=y | 68 | CONFIG_FB_MATROX=y |
67 | CONFIG_FB_MATROX_MILLENIUM=y | 69 | CONFIG_FB_MATROX_MILLENIUM=y |
68 | CONFIG_FB_MATROX_MYSTIQUE=y | 70 | CONFIG_FB_MATROX_MYSTIQUE=y |
71 | # CONFIG_VGA_CONSOLE is not set | ||
72 | CONFIG_MMC=y | ||
73 | CONFIG_MMC_ARMMMCI=y | ||
69 | CONFIG_RTC_CLASS=y | 74 | CONFIG_RTC_CLASS=y |
70 | CONFIG_RTC_DRV_PL030=y | 75 | CONFIG_RTC_DRV_PL030=y |
71 | CONFIG_EXT2_FS=y | 76 | CONFIG_EXT2_FS=y |
77 | CONFIG_VFAT_FS=y | ||
72 | CONFIG_TMPFS=y | 78 | CONFIG_TMPFS=y |
73 | CONFIG_JFFS2_FS=y | 79 | CONFIG_JFFS2_FS=y |
74 | CONFIG_CRAMFS=y | 80 | CONFIG_CRAMFS=y |
@@ -78,5 +84,7 @@ CONFIG_ROOT_NFS=y | |||
78 | CONFIG_NFSD=y | 84 | CONFIG_NFSD=y |
79 | CONFIG_NFSD_V3=y | 85 | CONFIG_NFSD_V3=y |
80 | CONFIG_PARTITION_ADVANCED=y | 86 | CONFIG_PARTITION_ADVANCED=y |
87 | CONFIG_NLS_CODEPAGE_437=y | ||
88 | CONFIG_NLS_ISO8859_1=y | ||
81 | CONFIG_MAGIC_SYSRQ=y | 89 | CONFIG_MAGIC_SYSRQ=y |
82 | CONFIG_DEBUG_KERNEL=y | 90 | CONFIG_DEBUG_KERNEL=y |
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 0e9ce8d9686e..38050b1c4800 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h | |||
@@ -130,8 +130,4 @@ struct mm_struct; | |||
130 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); | 130 | extern 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 | ||
133 | extern 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 7df239bcdf27..c4c87bc12231 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__ |
106 | extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); | 106 | extern 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) |
108 | extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask); | 108 | extern int l2x0_of_init(u32 aux_val, u32 aux_mask); |
109 | #else | 109 | #else |
110 | static inline int l2x0_of_init(__u32 aux_val, __u32 aux_mask) | 110 | static 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 43cab498bc27..73f84fa4f366 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 | |||
12 | extern void __iomem *it8152_base_address; | 15 | extern 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 5a526afb5f18..35c21c375d81 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 000000000000..5c5ca2ea62b0 --- /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 | |||
17 | static __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; | ||
27 | l_yes: | ||
28 | return true; | ||
29 | } | ||
30 | |||
31 | #endif /* __KERNEL__ */ | ||
32 | |||
33 | typedef u32 jump_label_t; | ||
34 | |||
35 | struct 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 6b884d2b0b69..e8567bb99dfc 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 a8997d71084e..fcb575747e5e 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 71605d9f8e42..a0b3cac0547c 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 | ||
22 | void __check_kvm_seq(struct mm_struct *mm); | 23 | void __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) \ | ||
144 | do { \ | ||
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 | |||
159 | static 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 c0efdd60966f..19c48deda70f 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 97b440c25c58..5838361c48b3 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) |
152 | extern void copy_page(void *to, const void *from); | 152 | extern 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 7523340afb8a..00cbe10a50e3 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 f4d7f56ee51f..5ac8d3d3e025 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 ee0363307918..aeae9c609df4 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 | |||
18 | extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); | 16 | extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); |
19 | extern void arm_dt_memblock_reserve(void); | 17 | extern 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 02b2f8203982..85fe61e73202 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 | |||
321 | static inline void local_flush_tlb_all(void) | 336 | static 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 5b29a6673625..f555bb3664dc 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 | ||
49 | extern void __init early_trap_init(void); | 49 | extern void __init early_trap_init(void *); |
50 | extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); | 50 | extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); |
51 | extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); | 51 | extern 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 3a274878412e..8269d8928742 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -7,6 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) | |||
7 | 7 | ||
8 | ifdef CONFIG_FUNCTION_TRACER | 8 | ifdef CONFIG_FUNCTION_TRACER |
9 | CFLAGS_REMOVE_ftrace.o = -pg | 9 | CFLAGS_REMOVE_ftrace.o = -pg |
10 | CFLAGS_REMOVE_insn.o = -pg | ||
11 | CFLAGS_REMOVE_patch.o = -pg | ||
10 | endif | 12 | endif |
11 | 13 | ||
12 | CFLAGS_REMOVE_return_address.o = -pg | 14 | CFLAGS_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 | ||
16 | obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ | 18 | obj-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 | ||
20 | obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o | 22 | obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o |
21 | 23 | ||
@@ -29,14 +31,14 @@ obj-$(CONFIG_ARTHUR) += arthur.o | |||
29 | obj-$(CONFIG_ISA_DMA) += dma-isa.o | 31 | obj-$(CONFIG_ISA_DMA) += dma-isa.o |
30 | obj-$(CONFIG_PCI) += bios32.o isa.o | 32 | obj-$(CONFIG_PCI) += bios32.o isa.o |
31 | obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o | 33 | obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o |
32 | obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o | ||
33 | obj-$(CONFIG_SMP) += smp.o smp_tlb.o | 34 | obj-$(CONFIG_SMP) += smp.o smp_tlb.o |
34 | obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o | 35 | obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o |
35 | obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o | 36 | obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o |
36 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 37 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o |
37 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 38 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o |
39 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o | ||
38 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | 40 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o |
39 | obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o | 41 | obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o |
40 | ifdef CONFIG_THUMB2_KERNEL | 42 | ifdef CONFIG_THUMB2_KERNEL |
41 | obj-$(CONFIG_KPROBES) += kprobes-thumb.o | 43 | obj-$(CONFIG_KPROBES) += kprobes-thumb.o |
42 | else | 44 | else |
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index 204e2160cfcc..e5a765c5f06a 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 | |||
158 | ENTRY(printascii) | 160 | ENTRY(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 |
179 | ENDPROC(printch) | 181 | ENDPROC(printch) |
182 | |||
183 | #else | ||
184 | |||
185 | ENTRY(printascii) | ||
186 | mov r1, r0 | ||
187 | mov r0, #0x04 @ SYS_WRITE0 | ||
188 | ARM( svc #0x123456 ) | ||
189 | THUMB( svc #0xab ) | ||
190 | mov pc, lr | ||
191 | ENDPROC(printascii) | ||
192 | |||
193 | ENTRY(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 | ||
200 | ENDPROC(printch) | ||
201 | |||
202 | #endif | ||
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index c0062ad1e847..df0bf0c8cb79 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 | ||
64 | static 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 | ||
94 | static 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 | |||
118 | static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | 66 | static 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 | ||
123 | static int ftrace_modify_code(unsigned long pc, unsigned long old, | 71 | static 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 | ||
142 | int ftrace_update_ftrace_func(ftrace_func_t func) | 100 | int 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 | ||
178 | int ftrace_make_nop(struct module *mod, | 134 | int 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 | ||
260 | static int ftrace_modify_graph_caller(bool enable) | 216 | static int ftrace_modify_graph_caller(bool enable) |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index a2e9694a68ee..3bf0c7f8b043 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 000000000000..ab312e516546 --- /dev/null +++ b/arch/arm/kernel/insn.c | |||
@@ -0,0 +1,61 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <asm/opcodes.h> | ||
3 | |||
4 | static 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 | |||
34 | static 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 | |||
54 | unsigned 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 000000000000..e96065da4dae --- /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 | |||
4 | static inline unsigned long | ||
5 | arm_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 | |||
14 | unsigned long | ||
15 | __arm_gen_branch(unsigned long pc, unsigned long addr, bool link); | ||
16 | |||
17 | static inline unsigned long | ||
18 | arm_gen_branch(unsigned long pc, unsigned long addr) | ||
19 | { | ||
20 | return __arm_gen_branch(pc, addr, false); | ||
21 | } | ||
22 | |||
23 | static inline unsigned long | ||
24 | arm_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 6a6a097edd61..71ccdbfed662 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 000000000000..4ce4f789446d --- /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 | |||
9 | static 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 | |||
27 | void 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 | |||
33 | void 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 129c1163248b..ab1869dac97a 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 | */ | ||
113 | static 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 | |||
121 | void __kprobes arch_arm_kprobe(struct kprobe *p) | 107 | void __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 | ||
144 | void __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) | |||
166 | int __kprobes __arch_disarm_kprobe(void *p) | 143 | int __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 56995983eed8..dfcdb9f7c126 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 | ||
57 | static 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 | |||
56 | void machine_crash_shutdown(struct pt_regs *regs) | 80 | void 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 000000000000..07314af47733 --- /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 | |||
11 | struct patch { | ||
12 | void *addr; | ||
13 | unsigned int insn; | ||
14 | }; | ||
15 | |||
16 | void __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 | |||
47 | static 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 | |||
56 | void __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 000000000000..b4731f2dac38 --- /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 | |||
4 | void patch_text(void *addr, unsigned int insn); | ||
5 | void __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 8a89d3b7626b..186c8cb982c5 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 4d7095af2ab3..00755d82e2f2 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 | */ | ||
615 | static 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 | |||
627 | static 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 | ||
1231 | static 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 | |||
1107 | static struct arm_pmu armv7pmu = { | 1237 | static 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 | |||
1298 | static 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 |
1168 | static struct arm_pmu *__init armv7_a8_pmu_init(void) | 1308 | static 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 | |||
1328 | static 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 7b9cddef6e53..2b7b017a20cd 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 | */ |
534 | static struct vm_area_struct gate_vma; | ||
534 | 535 | ||
535 | int vectors_user_mapping(void) | 536 | static 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 | } | ||
545 | arch_initcall(gate_vma_init); | ||
546 | |||
547 | struct vm_area_struct *get_gate_vma(struct mm_struct *mm) | ||
548 | { | ||
549 | return &gate_vma; | ||
550 | } | ||
551 | |||
552 | int 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 | |||
557 | int in_gate_area_no_mm(unsigned long addr) | ||
558 | { | ||
559 | return in_gate_area(NULL, addr); | ||
542 | } | 560 | } |
543 | 561 | ||
544 | const char *arch_vma_name(struct vm_area_struct *vma) | 562 | const 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 5416c7c12528..27d186abbc06 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 | |||
169 | static int sched_clock_suspend(void) | ||
170 | { | ||
171 | sched_clock_poll(sched_clock_timer.data); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static struct syscore_ops sched_clock_ops = { | ||
176 | .suspend = sched_clock_suspend, | ||
177 | }; | ||
178 | |||
179 | static int __init sched_clock_syscore_init(void) | ||
180 | { | ||
181 | register_syscore_ops(&sched_clock_ops); | ||
182 | return 0; | ||
183 | } | ||
184 | device_initcall(sched_clock_syscore_init); | ||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 9e0fdb3a1988..b91411371ae1 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 9e617bd4a146..7cb532fc8aa4 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 | */ |
67 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) | 67 | asmlinkage 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(¤t->sighand->siglock); | 70 | |
71 | current->saved_sigmask = current->blocked; | 71 | current->saved_sigmask = current->blocked; |
72 | siginitset(¤t->blocked, mask); | 72 | |
73 | recalc_sigpending(); | 73 | mask &= _BLOCKABLE; |
74 | spin_unlock_irq(¤t->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(¤t->sighand->siglock); | 284 | set_current_blocked(&set); |
284 | current->blocked = set; | ||
285 | recalc_sigpending(); | ||
286 | spin_unlock_irq(¤t->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 8f8cce2c46c4..2cee7d1eb958 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 | ||
61 | static DECLARE_COMPLETION(cpu_running); | ||
62 | |||
61 | int __cpuinit __cpu_up(unsigned int cpu) | 63 | int __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 8c57dd3680e9..fe31b22f18fd 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 cd77743472a2..778454750a6c 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 | ||
231 | static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) | 236 | static 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 | ||
787 | void __init early_trap_init(void) | 792 | void __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 e1969ce904dc..75da315b6587 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 | ||
29 | static struct clock_event_device clockevent_davinci; | 32 | static 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 | */ | ||
279 | static cycle_t read_dummy(struct clocksource *cs) | ||
280 | { | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | |||
285 | static struct clocksource clocksource_davinci = { | 278 | static 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 | */ |
295 | unsigned long long notrace sched_clock(void) | 288 | static 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 808b055289b2..410a112bb52e 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 9746aab14e9a..000000000000 --- 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 1a65d77bd55d..eaf6c6366ffa 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 1fbe6d190222..a19a1a2fcf6b 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 21a1d6cbef40..871f148ffd72 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 | ||
326 | static unsigned long timer_reload; | 327 | static unsigned long timer_reload; |
327 | 328 | ||
329 | static u32 notrace integrator_read_sched_clock(void) | ||
330 | { | ||
331 | return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); | ||
332 | } | ||
333 | |||
328 | static void integrator_clocksource_init(unsigned long inrate) | 334 | static 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 | ||
346 | static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; | 353 | static 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 be9ead4a3bcc..48a115a91d9d 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 36068f438f2b..f1ca9c122861 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 4be172c3cbe0..67e6f9a9d1a0 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 3588a5584153..bf5d8e195c3e 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 | ||
240 | MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform") | 241 | MACHINE_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 | ||
249 | MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform") | 250 | MACHINE_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 b148a9dc5a44..603542ae6fbd 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 | ||
44 | MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform") | 44 | MACHINE_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 d839fe6421e6..5cb769cd26d9 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 | ||
160 | static struct max8925_platform_data brownstone_max8925_info = { | 160 | static struct max8925_platform_data brownstone_max8925_info = { |
161 | .irq_base = IRQ_BOARD_START, | 161 | .irq_base = MMP_NR_IRQS, |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static struct i2c_board_info brownstone_twsi1_info[] = { | 164 | static struct i2c_board_info brownstone_twsi1_info[] = { |
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c index 2ee8cd7829dd..8059cc0905c6 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 | ||
31 | static unsigned long flint_pin_config[] __initdata = { | 32 | static 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 87765467de63..f516e74ce0d5 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 | ||
192 | MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform") | 192 | MACHINE_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 34635a0bbb59..d0e746626a3d 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 d21c5441a3d0..7895d277421e 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 96cf5c8fe47d..ff73249884d0 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 | ||
32 | static unsigned long jasper_pin_config[] __initdata = { | 33 | static unsigned long jasper_pin_config[] __initdata = { |
33 | /* UART1 */ | 34 | /* UART1 */ |
@@ -135,7 +136,7 @@ static struct max8925_power_pdata jasper_power_data = { | |||
135 | static struct max8925_platform_data jasper_max8925_info = { | 136 | static 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 | ||
141 | static struct i2c_board_info jasper_twsi1_info[] = { | 142 | static struct i2c_board_info jasper_twsi1_info[] = { |
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c index bc97170125bf..b28f9084dfff 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 | ||
102 | MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)") | 102 | MACHINE_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 0523e422990e..42bef6674ecf 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 | ||
84 | MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform") | 85 | MACHINE_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 e72c709da44f..3fc9ed21f97d 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 | ||
43 | static unsigned long ttc_dkb_pin_config[] __initdata = { | 43 | static unsigned long ttc_dkb_pin_config[] __initdata = { |
44 | /* UART2 */ | 44 | /* UART2 */ |
@@ -131,7 +131,7 @@ static struct platform_device *ttc_dkb_devices[] = { | |||
131 | static struct pca953x_platform_data max7312_data[] = { | 131 | static 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 75f4be40b3e5..812808254936 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 | ||
106 | static void __iomem *source_base; | 107 | static void __iomem *source_base; |
107 | 108 | ||
108 | static cycle_t msm_read_timer_count(struct clocksource *cs) | 109 | static 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 | ||
113 | static cycle_t msm_read_timer_count_shift(struct clocksource *cs) | 114 | static 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 | ||
170 | static notrace u32 msm_sched_clock_read(void) | ||
171 | { | ||
172 | return msm_clocksource.read(&msm_clocksource); | ||
173 | } | ||
174 | |||
169 | static void __init msm_timer_init(void) | 175 | static 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 | ||
237 | struct sys_timer msm_timer = { | 245 | struct 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 59eac1ee2820..000000000000 --- 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 b7a6091ce791..0d024b1e916d 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 */ |
168 | unsigned long long notrace sched_clock(void) | 169 | static 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 | ||
185 | static void __init sirfsoc_clockevent_init(void) | 174 | static 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 c91727d1fe09..9a8760b72913 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 895ee8c45009..638eebedc883 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, | |||
854 | MACHINE_START(CM_X300, "CM-X300 module") | 854 | MACHINE_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 29d5d541f602..b2f227d36125 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 0846d210cb05..bb6def8ec979 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 6ad3359063af..d88e7b37f1da 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 de9d45e673fd..c1fe32db4755 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, | |||
729 | MACHINE_START(CORGI, "SHARP Corgi") | 729 | MACHINE_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 | |||
741 | MACHINE_START(SHEPHERD, "SHARP Shepherd") | 742 | MACHINE_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 | |||
753 | MACHINE_START(HUSKY, "SHARP Husky") | 755 | MACHINE_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 fb5a51d834e5..67f0de37f46e 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) | |||
274 | MACHINE_START(CSB726, "Cogent CSB726") | 274 | MACHINE_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 84f2d7015cfe..166eee5b8a70 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 d80c0ba9a095..c1b65da26335 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) | |||
1301 | MACHINE_START(EM_X270, "Compulab EM-X270") | 1301 | MACHINE_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 | |||
1311 | MACHINE_START(EXEDA, "Compulab eXeda") | 1312 | MACHINE_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 ac3b1cef4751..e529a35a44ce 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) | |||
235 | MACHINE_START(GUMSTIX, "Gumstix") | 235 | MACHINE_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 fde6b4c873c4..e7dec589f014 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) | |||
205 | MACHINE_START(H5400, "HP iPAQ H5000") | 205 | MACHINE_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 26d069a9f900..2962de898da9 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) | |||
160 | MACHINE_START(HIMALAYA, "HTC Himalaya") | 160 | MACHINE_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 67400192ed3b..1d02eabc9c65 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) | |||
193 | MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") | 193 | MACHINE_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 8af1840e12cc..6ff466bd43e8 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) | |||
195 | MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") | 195 | MACHINE_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 32975adf3ca4..8765782dd955 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__ |
106 | struct irq_data; | 106 | struct irq_data; |
diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h index 4c2d11cd824d..1bfc4e822a41 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 e80a3db735c2..061d57009cee 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 169bf8f97af0..152efbf093f6 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 1fa80f4f80c8..31e0433d83ba 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) | |||
344 | MACHINE_START(PALMLD, "Palm LifeDrive") | 344 | MACHINE_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 5ba14316bd9c..0f6bd4fcfa3b 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 29b51b40f09d..e2d97eed07a7 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) | |||
539 | MACHINE_START(PALMTC, "Palm Tungsten|C") | 539 | MACHINE_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 5ebf49acb827..c054827c567f 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) | |||
358 | MACHINE_START(PALMTE2, "Palm Tungsten|E2") | 358 | MACHINE_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 ec8249156c08..fbdebee39a53 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 6170d76dfba8..9507605ed547 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) | |||
366 | MACHINE_START(PALMTX, "Palm T|X") | 366 | MACHINE_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 b2dff9d415eb..a97b59965bb9 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) | |||
401 | MACHINE_START(PALMZ72, "Palm Zire72") | 401 | MACHINE_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 1570d457fea3..dffb7e813d98 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 22818c7694a8..7d691e51cb54 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 0fe354efb931..86c95a5d8533 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 abf355d0c92f..df2ab0fb2ace 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 b0656e158d90..adb601a3762f 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 |
1007 | MACHINE_START(INTELMOTE2, "IMOTE 2") | 1007 | MACHINE_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 9fb38e80e076..736bfdc50ee6 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 b503049d6d26..3d6c9bd90de6 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 0f30af617d8f..2b6ac00b2cd9 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 7a3d342a7732..130379fb9d0f 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 1f5cfa96f6d6..c57ab636ea9c 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) | |||
718 | MACHINE_START(VPAC270, "Voipac PXA270") | 718 | MACHINE_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 4bbe9a36fe74..4275713ccd10 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 b6476848b561..fa8619970841 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) | |||
721 | MACHINE_START(ZIPIT2, "Zipit Z2") | 721 | MACHINE_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 060e5644c49c..34560cab45d9 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -100,6 +100,10 @@ config MACH_MARZEN | |||
100 | 100 | ||
101 | comment "SH-Mobile System Configuration" | 101 | comment "SH-Mobile System Configuration" |
102 | 102 | ||
103 | config CPU_HAS_INTEVT | ||
104 | bool | ||
105 | default y | ||
106 | |||
103 | menu "Memory configuration" | 107 | menu "Memory configuration" |
104 | 108 | ||
105 | config MEMORY_START | 109 | config MEMORY_START |
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index f50d7c8b1221..f9153294e928 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 8b2124da245d..a71ae802cc49 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 b627e89037f5..39b6cf85ced6 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 46d757d2759d..0e5a39c670bc 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 61c067294660..10e9e6967903 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 ca609502d6cd..a125d4e114ec 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 cbd5e4cd06d2..ef0e13bf0b3a 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 dcb714f4d75a..4e686cc201fc 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 272c84c20c83..09c42afcb22d 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 cfde9bfc3669..5bf776495b75 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 89afcaba99a1..6447e0af52d4 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 2af4e6e9bc5b..b84a460a3405 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 9857595eaa79..15b408f58272 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 74e52341dd1b..14edb5cffa7f 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 6820d785493d..12c6f529ab89 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 a51e1a1e6996..2e3074ab75b3 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 4e818b7de781..2fe8f83ca124 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 9f146095098b..d576a6abbade 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 b6a0734a738e..5bebffc10455 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 13522d86685e..0088cd388a84 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 b1e192ba8c24..a53fd2aaa2f4 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -30,13 +30,13 @@ | |||
30 | 30 | ||
31 | static void __iomem *l2x0_base; | 31 | static void __iomem *l2x0_base; |
32 | static DEFINE_RAW_SPINLOCK(l2x0_lock); | 32 | static DEFINE_RAW_SPINLOCK(l2x0_lock); |
33 | static uint32_t l2x0_way_mask; /* Bitmask of active ways */ | 33 | static u32 l2x0_way_mask; /* Bitmask of active ways */ |
34 | static uint32_t l2x0_size; | 34 | static u32 l2x0_size; |
35 | 35 | ||
36 | struct l2x0_regs l2x0_saved_regs; | 36 | struct l2x0_regs l2x0_saved_regs; |
37 | 37 | ||
38 | struct l2x0_of_data { | 38 | struct 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 | ||
291 | static void l2x0_unlock(__u32 cache_id) | 291 | static 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 | ||
310 | void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) | 310 | void __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 |
390 | static void __init l2x0_of_setup(const struct device_node *np, | 390 | static 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 | ||
424 | static void __init pl310_of_setup(const struct device_node *np, | 424 | static 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 | ||
551 | int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask) | 551 | int __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 ec8c3befb9c8..1267e64133b9 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 8b03a5814d00..b9bcc9d79176 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 | |||
30 | static DEFINE_RAW_SPINLOCK(v6_lock); | 27 | static 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 | */ |
112 | static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr) | 106 | static 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 439d106ae638..0fb85025344d 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 1aa664a1999f..db23ae4aaaab 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) | |||
214 | core_initcall(consistent_init); | 214 | core_initcall(consistent_init); |
215 | 215 | ||
216 | static void * | 216 | static 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 | ||
328 | static void * | 329 | static 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 | } |
379 | EXPORT_SYMBOL(dma_alloc_coherent); | 381 | EXPORT_SYMBOL(dma_alloc_coherent); |
380 | 382 | ||
@@ -386,7 +388,8 @@ void * | |||
386 | dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) | 388 | dma_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 | } |
391 | EXPORT_SYMBOL(dma_alloc_writecombine); | 394 | EXPORT_SYMBOL(dma_alloc_writecombine); |
392 | 395 | ||
@@ -723,6 +726,9 @@ EXPORT_SYMBOL(dma_set_mask); | |||
723 | 726 | ||
724 | static int __init dma_debug_do_init(void) | 727 | static 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 5bdff5c3e6cb..9055b5a84ec5 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 062d61a1f87d..77458548e031 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 | |||
27 | static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) | 25 | static 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 | ||
42 | static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len) | 39 | static 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 5a21505d7550..21b9e1bf9b77 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) | |||
132 | struct page *kmap_atomic_to_page(const void *ptr) | 129 | struct 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 245a55a0a5bb..595079fa9d1d 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 70f6d3ea4834..27f4a619b35d 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 */ |
4 | extern pmd_t *top_pmd; | 4 | extern 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 | |||
19 | static 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 | |||
26 | static 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 | ||
8 | static inline pmd_t *pmd_off_k(unsigned long virt) | 32 | static 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 cd439c1dd506..b86f8933ff91 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 036fdbfdd62f..a631016e1f8f 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 | ||
37 | struct arm_vmregion * | 40 | struct arm_vmregion * |
38 | arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, | 41 | arm_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 | ||
139 | static 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 | |||
151 | static 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 | |||
158 | static 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 | |||
164 | static 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 | |||
170 | static 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 | |||
177 | static 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 | |||
188 | static 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 | |||
195 | int 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 | ||
201 | int 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 15e9f044db9f..162be662c088 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 | ||
24 | struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t); | 25 | struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *); |
25 | struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); | 26 | struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); |
26 | struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); | 27 | struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); |
27 | void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); | 28 | void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); |
28 | 29 | ||
30 | int 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 000000000000..c2c10841b6be --- /dev/null +++ b/arch/arm/net/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | # ARM-specific networking code | ||
2 | |||
3 | obj-$(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 000000000000..62135849f48b --- /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 | |||
56 | struct 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 | |||
72 | int bpf_jit_enable __read_mostly; | ||
73 | |||
74 | static 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 | |||
84 | static 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 | |||
94 | static 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 | */ | ||
108 | static u32 jit_udiv(u32 dividend, u32 divisor) | ||
109 | { | ||
110 | return dividend / divisor; | ||
111 | } | ||
112 | |||
113 | static 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 | */ | ||
124 | static inline void emit(u32 inst, struct jit_ctx *ctx) | ||
125 | { | ||
126 | _emit(ARM_COND_AL, inst, ctx); | ||
127 | } | ||
128 | |||
129 | static 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 | |||
153 | static 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 | |||
159 | static 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 | |||
178 | static 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 | |||
219 | static 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 | |||
245 | static 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 | |||
258 | static 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 | */ | ||
297 | static 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 | |||
308 | static 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 | |||
320 | static 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 | |||
332 | static 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 | |||
339 | static 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 | |||
349 | static 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 | |||
357 | static 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 | |||
365 | static 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. */ | ||
378 | static 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 | |||
404 | static 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 | |||
416 | static 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 | |||
430 | static 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 | |||
451 | static 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 | |||
459 | static 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; | ||
500 | load: | ||
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); | ||
505 | load_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; | ||
549 | load_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; | ||
694 | cmp_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 | } | ||
702 | cond_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; | ||
721 | cmp_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); | ||
751 | b_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 | |||
830 | void 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; | ||
895 | out: | ||
896 | kfree(ctx.offsets); | ||
897 | return; | ||
898 | } | ||
899 | |||
900 | static void bpf_jit_free_worker(struct work_struct *work) | ||
901 | { | ||
902 | module_free(NULL, work); | ||
903 | } | ||
904 | |||
905 | void 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 000000000000..99ae5e3f46d2 --- /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 bca4914b4b9d..4c48c8b60b54 100644 --- a/arch/arm/plat-nomadik/Kconfig +++ b/arch/arm/plat-nomadik/Kconfig | |||
@@ -23,7 +23,6 @@ config HAS_MTU | |||
23 | config NOMADIK_MTU_SCHED_CLOCK | 23 | config 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 52353beb369d..043f7b02a9e7 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 | ||
13 | config PLAT_VERSATILE_SCHED_CLOCK | 13 | config PLAT_VERSATILE_SCHED_CLOCK |
14 | def_bool y if !ARCH_INTEGRATOR_AP | 14 | def_bool y |
15 | select HAVE_SCHED_CLOCK | ||
16 | 15 | ||
17 | endif | 16 | endif |