diff options
55 files changed, 1177 insertions, 522 deletions
diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt index c0c7626fd0ff..b513cb8196fe 100644 --- a/Documentation/devicetree/bindings/arm/l2cc.txt +++ b/Documentation/devicetree/bindings/arm/l2cc.txt | |||
@@ -7,20 +7,21 @@ The ARM L2 cache representation in the device tree should be done as follows: | |||
7 | Required properties: | 7 | Required properties: |
8 | 8 | ||
9 | - compatible : should be one of: | 9 | - compatible : should be one of: |
10 | "arm,pl310-cache" | 10 | "arm,pl310-cache" |
11 | "arm,l220-cache" | 11 | "arm,l220-cache" |
12 | "arm,l210-cache" | 12 | "arm,l210-cache" |
13 | "marvell,aurora-system-cache": Marvell Controller designed to be | 13 | "bcm,bcm11351-a2-pl310-cache": DEPRECATED by "brcm,bcm11351-a2-pl310-cache" |
14 | "brcm,bcm11351-a2-pl310-cache": For Broadcom bcm11351 chipset where an | ||
15 | offset needs to be added to the address before passing down to the L2 | ||
16 | cache controller | ||
17 | "marvell,aurora-system-cache": Marvell Controller designed to be | ||
14 | compatible with the ARM one, with system cache mode (meaning | 18 | compatible with the ARM one, with system cache mode (meaning |
15 | maintenance operations on L1 are broadcasted to the L2 and L2 | 19 | maintenance operations on L1 are broadcasted to the L2 and L2 |
16 | performs the same operation). | 20 | performs the same operation). |
17 | "marvell,"aurora-outer-cache: Marvell Controller designed to be | 21 | "marvell,aurora-outer-cache": Marvell Controller designed to be |
18 | compatible with the ARM one with outer cache mode. | 22 | compatible with the ARM one with outer cache mode. |
19 | "brcm,bcm11351-a2-pl310-cache": For Broadcom bcm11351 chipset where an | 23 | "marvell,tauros3-cache": Marvell Tauros3 cache controller, compatible |
20 | offset needs to be added to the address before passing down to the L2 | 24 | with arm,pl310-cache controller. |
21 | cache controller | ||
22 | "bcm,bcm11351-a2-pl310-cache": DEPRECATED by | ||
23 | "brcm,bcm11351-a2-pl310-cache" | ||
24 | - cache-unified : Specifies the cache is a unified cache. | 25 | - cache-unified : Specifies the cache is a unified cache. |
25 | - cache-level : Should be set to 2 for a level 2 cache. | 26 | - cache-level : Should be set to 2 for a level 2 cache. |
26 | - reg : Physical base address and size of cache controller's memory mapped | 27 | - reg : Physical base address and size of cache controller's memory mapped |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ab1689c96a71..0b6d8bf1bc34 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -6,12 +6,13 @@ config ARM | |||
6 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | 6 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
7 | select ARCH_HAVE_CUSTOM_GPIO_H | 7 | select ARCH_HAVE_CUSTOM_GPIO_H |
8 | select ARCH_MIGHT_HAVE_PC_PARPORT | 8 | select ARCH_MIGHT_HAVE_PC_PARPORT |
9 | select ARCH_USE_BUILTIN_BSWAP | ||
9 | select ARCH_USE_CMPXCHG_LOCKREF | 10 | select ARCH_USE_CMPXCHG_LOCKREF |
10 | select ARCH_WANT_IPC_PARSE_VERSION | 11 | select ARCH_WANT_IPC_PARSE_VERSION |
11 | select BUILDTIME_EXTABLE_SORT if MMU | 12 | select BUILDTIME_EXTABLE_SORT if MMU |
12 | select CLONE_BACKWARDS | 13 | select CLONE_BACKWARDS |
13 | select CPU_PM if (SUSPEND || CPU_IDLE) | 14 | select CPU_PM if (SUSPEND || CPU_IDLE) |
14 | select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU | 15 | select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS |
15 | select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) | 16 | select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) |
16 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP | 17 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP |
17 | select GENERIC_IDLE_POLL_SETUP | 18 | select GENERIC_IDLE_POLL_SETUP |
@@ -36,6 +37,7 @@ config ARM | |||
36 | select HAVE_DMA_ATTRS | 37 | select HAVE_DMA_ATTRS |
37 | select HAVE_DMA_CONTIGUOUS if MMU | 38 | select HAVE_DMA_CONTIGUOUS if MMU |
38 | select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) | 39 | select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) |
40 | select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU | ||
39 | select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) | 41 | select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) |
40 | select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) | 42 | select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) |
41 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) | 43 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) |
@@ -63,6 +65,7 @@ config ARM | |||
63 | select IRQ_FORCED_THREADING | 65 | select IRQ_FORCED_THREADING |
64 | select KTIME_SCALAR | 66 | select KTIME_SCALAR |
65 | select MODULES_USE_ELF_REL | 67 | select MODULES_USE_ELF_REL |
68 | select NO_BOOTMEM | ||
66 | select OLD_SIGACTION | 69 | select OLD_SIGACTION |
67 | select OLD_SIGSUSPEND3 | 70 | select OLD_SIGSUSPEND3 |
68 | select PERF_USE_VMALLOC | 71 | select PERF_USE_VMALLOC |
@@ -1651,9 +1654,6 @@ config HZ | |||
1651 | config SCHED_HRTICK | 1654 | config SCHED_HRTICK |
1652 | def_bool HIGH_RES_TIMERS | 1655 | def_bool HIGH_RES_TIMERS |
1653 | 1656 | ||
1654 | config SCHED_HRTICK | ||
1655 | def_bool HIGH_RES_TIMERS | ||
1656 | |||
1657 | config THUMB2_KERNEL | 1657 | config THUMB2_KERNEL |
1658 | bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY | 1658 | bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY |
1659 | depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K | 1659 | depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K |
@@ -1934,6 +1934,7 @@ config ZBOOT_ROM_BSS | |||
1934 | config ZBOOT_ROM | 1934 | config ZBOOT_ROM |
1935 | bool "Compressed boot loader in ROM/flash" | 1935 | bool "Compressed boot loader in ROM/flash" |
1936 | depends on ZBOOT_ROM_TEXT != ZBOOT_ROM_BSS | 1936 | depends on ZBOOT_ROM_TEXT != ZBOOT_ROM_BSS |
1937 | depends on !ARM_APPENDED_DTB && !XIP_KERNEL && !AUTO_ZRELADDR | ||
1937 | help | 1938 | help |
1938 | Say Y here if you intend to execute your compressed kernel image | 1939 | Say Y here if you intend to execute your compressed kernel image |
1939 | (zImage) directly from ROM or flash. If unsure, say N. | 1940 | (zImage) directly from ROM or flash. If unsure, say N. |
@@ -1969,7 +1970,7 @@ endchoice | |||
1969 | 1970 | ||
1970 | config ARM_APPENDED_DTB | 1971 | config ARM_APPENDED_DTB |
1971 | bool "Use appended device tree blob to zImage (EXPERIMENTAL)" | 1972 | bool "Use appended device tree blob to zImage (EXPERIMENTAL)" |
1972 | depends on OF && !ZBOOT_ROM | 1973 | depends on OF |
1973 | help | 1974 | help |
1974 | With this option, the boot code will look for a device tree binary | 1975 | With this option, the boot code will look for a device tree binary |
1975 | (DTB) appended to zImage | 1976 | (DTB) appended to zImage |
@@ -2057,7 +2058,7 @@ endchoice | |||
2057 | 2058 | ||
2058 | config XIP_KERNEL | 2059 | config XIP_KERNEL |
2059 | bool "Kernel Execute-In-Place from ROM" | 2060 | bool "Kernel Execute-In-Place from ROM" |
2060 | depends on !ZBOOT_ROM && !ARM_LPAE && !ARCH_MULTIPLATFORM | 2061 | depends on !ARM_LPAE && !ARCH_MULTIPLATFORM |
2061 | help | 2062 | help |
2062 | Execute-In-Place allows the kernel to run from non-volatile storage | 2063 | Execute-In-Place allows the kernel to run from non-volatile storage |
2063 | directly addressable by the CPU, such as NOR flash. This saves RAM | 2064 | directly addressable by the CPU, such as NOR flash. This saves RAM |
@@ -2120,7 +2121,6 @@ config CRASH_DUMP | |||
2120 | 2121 | ||
2121 | config AUTO_ZRELADDR | 2122 | config AUTO_ZRELADDR |
2122 | bool "Auto calculation of the decompressed kernel image address" | 2123 | bool "Auto calculation of the decompressed kernel image address" |
2123 | depends on !ZBOOT_ROM | ||
2124 | help | 2124 | help |
2125 | ZRELADDR is the physical address where the decompressed kernel | 2125 | ZRELADDR is the physical address where the decompressed kernel |
2126 | image will be placed. If AUTO_ZRELADDR is selected, the address | 2126 | image will be placed. If AUTO_ZRELADDR is selected, the address |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 5765abf5ce84..9afabbb5e798 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -2,6 +2,18 @@ menu "Kernel hacking" | |||
2 | 2 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | config ARM_PTDUMP | ||
6 | bool "Export kernel pagetable layout to userspace via debugfs" | ||
7 | depends on DEBUG_KERNEL | ||
8 | select DEBUG_FS | ||
9 | ---help--- | ||
10 | Say Y here if you want to show the kernel pagetable layout in a | ||
11 | debugfs file. This information is only useful for kernel developers | ||
12 | who are working in architecture specific areas of the kernel. | ||
13 | It is probably not a good idea to enable this feature in a production | ||
14 | kernel. | ||
15 | If in doubt, say "N" | ||
16 | |||
5 | config STRICT_DEVMEM | 17 | config STRICT_DEVMEM |
6 | bool "Filter access to /dev/mem" | 18 | bool "Filter access to /dev/mem" |
7 | depends on MMU | 19 | depends on MMU |
@@ -94,6 +106,17 @@ choice | |||
94 | depends on ARCH_BCM2835 | 106 | depends on ARCH_BCM2835 |
95 | select DEBUG_UART_PL01X | 107 | select DEBUG_UART_PL01X |
96 | 108 | ||
109 | config DEBUG_BCM_KONA_UART | ||
110 | bool "Kernel low-level debugging messages via BCM KONA UART" | ||
111 | depends on ARCH_BCM | ||
112 | select DEBUG_UART_8250 | ||
113 | help | ||
114 | Say Y here if you want kernel low-level debugging support | ||
115 | on Broadcom SoC platforms. | ||
116 | This low level debug works for Broadcom | ||
117 | mobile SoCs in the Kona family of chips (e.g. bcm28155, | ||
118 | bcm11351, etc...) | ||
119 | |||
97 | config DEBUG_CLPS711X_UART1 | 120 | config DEBUG_CLPS711X_UART1 |
98 | bool "Kernel low-level debugging messages via UART1" | 121 | bool "Kernel low-level debugging messages via UART1" |
99 | depends on ARCH_CLPS711X | 122 | depends on ARCH_CLPS711X |
@@ -988,6 +1011,7 @@ config DEBUG_UART_PHYS | |||
988 | default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 | 1011 | default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 |
989 | default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 | 1012 | default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 |
990 | default 0x20201000 if DEBUG_BCM2835 | 1013 | default 0x20201000 if DEBUG_BCM2835 |
1014 | default 0x3e000000 if DEBUG_BCM_KONA_UART | ||
991 | default 0x4000e400 if DEBUG_LL_UART_EFM32 | 1015 | default 0x4000e400 if DEBUG_LL_UART_EFM32 |
992 | default 0x40090000 if ARCH_LPC32XX | 1016 | default 0x40090000 if ARCH_LPC32XX |
993 | default 0x40100000 if DEBUG_PXA_UART1 | 1017 | default 0x40100000 if DEBUG_PXA_UART1 |
@@ -1049,6 +1073,7 @@ config DEBUG_UART_VIRT | |||
1049 | default 0xfe018000 if DEBUG_MMP_UART3 | 1073 | default 0xfe018000 if DEBUG_MMP_UART3 |
1050 | default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART | 1074 | default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART |
1051 | default 0xfe230000 if DEBUG_PICOXCELL_UART | 1075 | default 0xfe230000 if DEBUG_PICOXCELL_UART |
1076 | default 0xfe300000 if DEBUG_BCM_KONA_UART | ||
1052 | default 0xfe800000 if ARCH_IOP32X | 1077 | default 0xfe800000 if ARCH_IOP32X |
1053 | default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HI3716_UART | 1078 | default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HI3716_UART |
1054 | default 0xfeb24000 if DEBUG_RK3X_UART0 | 1079 | default 0xfeb24000 if DEBUG_RK3X_UART0 |
@@ -1091,7 +1116,8 @@ config DEBUG_UART_8250_WORD | |||
1091 | default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \ | 1116 | default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \ |
1092 | ARCH_KEYSTONE || \ | 1117 | ARCH_KEYSTONE || \ |
1093 | DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ | 1118 | DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ |
1094 | DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1 | 1119 | DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1 || \ |
1120 | DEBUG_BCM_KONA_UART | ||
1095 | 1121 | ||
1096 | config DEBUG_UART_8250_FLOW_CONTROL | 1122 | config DEBUG_UART_8250_FLOW_CONTROL |
1097 | bool "Enable flow control for 8250 UART" | 1123 | bool "Enable flow control for 8250 UART" |
@@ -1150,4 +1176,15 @@ config PID_IN_CONTEXTIDR | |||
1150 | additional instructions during context switch. Say Y here only if you | 1176 | additional instructions during context switch. Say Y here only if you |
1151 | are planning to use hardware trace tools with this kernel. | 1177 | are planning to use hardware trace tools with this kernel. |
1152 | 1178 | ||
1179 | config DEBUG_SET_MODULE_RONX | ||
1180 | bool "Set loadable kernel module data as NX and text as RO" | ||
1181 | depends on MODULES | ||
1182 | ---help--- | ||
1183 | This option helps catch unintended modifications to loadable | ||
1184 | kernel module's text and read-only data. It also prevents execution | ||
1185 | of module data. Such protection may interfere with run-time code | ||
1186 | patching and dynamic kernel tracing - and they might also protect | ||
1187 | against certain classes of kernel exploits. | ||
1188 | If in doubt, say "N". | ||
1189 | |||
1153 | endmenu | 1190 | endmenu |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index e7190bb5998e..4bb86d9a749d 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -108,12 +108,12 @@ endif | |||
108 | 108 | ||
109 | targets := vmlinux vmlinux.lds \ | 109 | targets := vmlinux vmlinux.lds \ |
110 | piggy.$(suffix_y) piggy.$(suffix_y).o \ | 110 | piggy.$(suffix_y) piggy.$(suffix_y).o \ |
111 | lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \ | 111 | lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S bswapsdi2.o \ |
112 | font.o font.c head.o misc.o $(OBJS) | 112 | bswapsdi2.S font.o font.c head.o misc.o $(OBJS) |
113 | 113 | ||
114 | # Make sure files are removed during clean | 114 | # Make sure files are removed during clean |
115 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \ | 115 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \ |
116 | lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \ | 116 | lib1funcs.S ashldi3.S bswapsdi2.S $(libfdt) $(libfdt_hdrs) \ |
117 | hyp-stub.S | 117 | hyp-stub.S |
118 | 118 | ||
119 | ifeq ($(CONFIG_FUNCTION_TRACER),y) | 119 | ifeq ($(CONFIG_FUNCTION_TRACER),y) |
@@ -156,6 +156,12 @@ ashldi3 = $(obj)/ashldi3.o | |||
156 | $(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S | 156 | $(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S |
157 | $(call cmd,shipped) | 157 | $(call cmd,shipped) |
158 | 158 | ||
159 | # For __bswapsi2, __bswapdi2 | ||
160 | bswapsdi2 = $(obj)/bswapsdi2.o | ||
161 | |||
162 | $(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S | ||
163 | $(call cmd,shipped) | ||
164 | |||
159 | # We need to prevent any GOTOFF relocs being used with references | 165 | # We need to prevent any GOTOFF relocs being used with references |
160 | # to symbols in the .bss section since we cannot relocate them | 166 | # to symbols in the .bss section since we cannot relocate them |
161 | # independently from the rest at run time. This can be achieved by | 167 | # independently from the rest at run time. This can be achieved by |
@@ -177,7 +183,8 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \ | |||
177 | fi | 183 | fi |
178 | 184 | ||
179 | $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ | 185 | $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ |
180 | $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE | 186 | $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \ |
187 | $(bswapsdi2) FORCE | ||
181 | @$(check_for_multiple_zreladdr) | 188 | @$(check_for_multiple_zreladdr) |
182 | $(call if_changed,ld) | 189 | $(call if_changed,ld) |
183 | @$(check_for_bad_syms) | 190 | @$(check_for_bad_syms) |
diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c index 26020a03f659..1e361abc29eb 100644 --- a/arch/arm/common/mcpm_entry.c +++ b/arch/arm/common/mcpm_entry.c | |||
@@ -35,8 +35,7 @@ void mcpm_set_early_poke(unsigned cpu, unsigned cluster, | |||
35 | unsigned long *poke = &mcpm_entry_early_pokes[cluster][cpu][0]; | 35 | unsigned long *poke = &mcpm_entry_early_pokes[cluster][cpu][0]; |
36 | poke[0] = poke_phys_addr; | 36 | poke[0] = poke_phys_addr; |
37 | poke[1] = poke_val; | 37 | poke[1] = poke_val; |
38 | __cpuc_flush_dcache_area((void *)poke, 8); | 38 | __sync_cache_range_w(poke, 2 * sizeof(*poke)); |
39 | outer_clean_range(__pa(poke), __pa(poke + 2)); | ||
40 | } | 39 | } |
41 | 40 | ||
42 | static const struct mcpm_platform_ops *platform_ops; | 41 | static const struct mcpm_platform_ops *platform_ops; |
@@ -167,7 +166,7 @@ void __mcpm_cpu_down(unsigned int cpu, unsigned int cluster) | |||
167 | dmb(); | 166 | dmb(); |
168 | mcpm_sync.clusters[cluster].cpus[cpu].cpu = CPU_DOWN; | 167 | mcpm_sync.clusters[cluster].cpus[cpu].cpu = CPU_DOWN; |
169 | sync_cache_w(&mcpm_sync.clusters[cluster].cpus[cpu].cpu); | 168 | sync_cache_w(&mcpm_sync.clusters[cluster].cpus[cpu].cpu); |
170 | dsb_sev(); | 169 | sev(); |
171 | } | 170 | } |
172 | 171 | ||
173 | /* | 172 | /* |
@@ -183,7 +182,7 @@ void __mcpm_outbound_leave_critical(unsigned int cluster, int state) | |||
183 | dmb(); | 182 | dmb(); |
184 | mcpm_sync.clusters[cluster].cluster = state; | 183 | mcpm_sync.clusters[cluster].cluster = state; |
185 | sync_cache_w(&mcpm_sync.clusters[cluster].cluster); | 184 | sync_cache_w(&mcpm_sync.clusters[cluster].cluster); |
186 | dsb_sev(); | 185 | sev(); |
187 | } | 186 | } |
188 | 187 | ||
189 | /* | 188 | /* |
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index e691ec91e4d3..b2e298a90d76 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h | |||
@@ -254,25 +254,59 @@ static inline int constant_fls(int x) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | /* | 256 | /* |
257 | * On ARMv5 and above those functions can be implemented around | 257 | * On ARMv5 and above those functions can be implemented around the |
258 | * the clz instruction for much better code efficiency. | 258 | * clz instruction for much better code efficiency. __clz returns |
259 | * the number of leading zeros, zero input will return 32, and | ||
260 | * 0x80000000 will return 0. | ||
259 | */ | 261 | */ |
262 | static inline unsigned int __clz(unsigned int x) | ||
263 | { | ||
264 | unsigned int ret; | ||
265 | |||
266 | asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); | ||
260 | 267 | ||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * fls() returns zero if the input is zero, otherwise returns the bit | ||
273 | * position of the last set bit, where the LSB is 1 and MSB is 32. | ||
274 | */ | ||
261 | static inline int fls(int x) | 275 | static inline int fls(int x) |
262 | { | 276 | { |
263 | int ret; | ||
264 | |||
265 | if (__builtin_constant_p(x)) | 277 | if (__builtin_constant_p(x)) |
266 | return constant_fls(x); | 278 | return constant_fls(x); |
267 | 279 | ||
268 | asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); | 280 | return 32 - __clz(x); |
269 | ret = 32 - ret; | 281 | } |
270 | return ret; | 282 | |
283 | /* | ||
284 | * __fls() returns the bit position of the last bit set, where the | ||
285 | * LSB is 0 and MSB is 31. Zero input is undefined. | ||
286 | */ | ||
287 | static inline unsigned long __fls(unsigned long x) | ||
288 | { | ||
289 | return fls(x) - 1; | ||
290 | } | ||
291 | |||
292 | /* | ||
293 | * ffs() returns zero if the input was zero, otherwise returns the bit | ||
294 | * position of the first set bit, where the LSB is 1 and MSB is 32. | ||
295 | */ | ||
296 | static inline int ffs(int x) | ||
297 | { | ||
298 | return fls(x & -x); | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | * __ffs() returns the bit position of the first bit set, where the | ||
303 | * LSB is 0 and MSB is 31. Zero input is undefined. | ||
304 | */ | ||
305 | static inline unsigned long __ffs(unsigned long x) | ||
306 | { | ||
307 | return ffs(x) - 1; | ||
271 | } | 308 | } |
272 | 309 | ||
273 | #define __fls(x) (fls(x) - 1) | ||
274 | #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) | ||
275 | #define __ffs(x) (ffs(x) - 1) | ||
276 | #define ffz(x) __ffs( ~(x) ) | 310 | #define ffz(x) __ffs( ~(x) ) |
277 | 311 | ||
278 | #endif | 312 | #endif |
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index ee753f1749cd..e9a49fe0284e 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -481,4 +481,9 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size) | |||
481 | : : : "r0","r1","r2","r3","r4","r5","r6","r7", \ | 481 | : : : "r0","r1","r2","r3","r4","r5","r6","r7", \ |
482 | "r9","r10","lr","memory" ) | 482 | "r9","r10","lr","memory" ) |
483 | 483 | ||
484 | int set_memory_ro(unsigned long addr, int numpages); | ||
485 | int set_memory_rw(unsigned long addr, int numpages); | ||
486 | int set_memory_x(unsigned long addr, int numpages); | ||
487 | int set_memory_nx(unsigned long addr, int numpages); | ||
488 | |||
484 | #endif | 489 | #endif |
diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h index 6dcc16430868..523315115478 100644 --- a/arch/arm/include/asm/checksum.h +++ b/arch/arm/include/asm/checksum.h | |||
@@ -87,19 +87,33 @@ static inline __wsum | |||
87 | csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, | 87 | csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, |
88 | unsigned short proto, __wsum sum) | 88 | unsigned short proto, __wsum sum) |
89 | { | 89 | { |
90 | __asm__( | 90 | u32 lenprot = len | proto << 16; |
91 | "adds %0, %1, %2 @ csum_tcpudp_nofold \n\ | 91 | if (__builtin_constant_p(sum) && sum == 0) { |
92 | adcs %0, %0, %3 \n" | 92 | __asm__( |
93 | "adds %0, %1, %2 @ csum_tcpudp_nofold0 \n\t" | ||
93 | #ifdef __ARMEB__ | 94 | #ifdef __ARMEB__ |
94 | "adcs %0, %0, %4 \n" | 95 | "adcs %0, %0, %3 \n\t" |
95 | #else | 96 | #else |
96 | "adcs %0, %0, %4, lsl #8 \n" | 97 | "adcs %0, %0, %3, ror #8 \n\t" |
97 | #endif | 98 | #endif |
98 | "adcs %0, %0, %5 \n\ | 99 | "adc %0, %0, #0" |
99 | adc %0, %0, #0" | 100 | : "=&r" (sum) |
100 | : "=&r"(sum) | 101 | : "r" (daddr), "r" (saddr), "r" (lenprot) |
101 | : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto)) | 102 | : "cc"); |
102 | : "cc"); | 103 | } else { |
104 | __asm__( | ||
105 | "adds %0, %1, %2 @ csum_tcpudp_nofold \n\t" | ||
106 | "adcs %0, %0, %3 \n\t" | ||
107 | #ifdef __ARMEB__ | ||
108 | "adcs %0, %0, %4 \n\t" | ||
109 | #else | ||
110 | "adcs %0, %0, %4, ror #8 \n\t" | ||
111 | #endif | ||
112 | "adc %0, %0, #0" | ||
113 | : "=&r"(sum) | ||
114 | : "r" (sum), "r" (daddr), "r" (saddr), "r" (lenprot) | ||
115 | : "cc"); | ||
116 | } | ||
103 | return sum; | 117 | return sum; |
104 | } | 118 | } |
105 | /* | 119 | /* |
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 3b2c40b5bfa2..6795ff743b3d 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h | |||
@@ -131,6 +131,7 @@ struct l2x0_regs { | |||
131 | unsigned long prefetch_ctrl; | 131 | unsigned long prefetch_ctrl; |
132 | unsigned long pwr_ctrl; | 132 | unsigned long pwr_ctrl; |
133 | unsigned long ctrl; | 133 | unsigned long ctrl; |
134 | unsigned long aux2_ctrl; | ||
134 | }; | 135 | }; |
135 | 136 | ||
136 | extern struct l2x0_regs l2x0_saved_regs; | 137 | extern struct l2x0_regs l2x0_saved_regs; |
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h index 2fe141fcc8d6..f98c7f32c9c8 100644 --- a/arch/arm/include/asm/mach/map.h +++ b/arch/arm/include/asm/mach/map.h | |||
@@ -22,18 +22,21 @@ struct map_desc { | |||
22 | }; | 22 | }; |
23 | 23 | ||
24 | /* types 0-3 are defined in asm/io.h */ | 24 | /* types 0-3 are defined in asm/io.h */ |
25 | #define MT_UNCACHED 4 | 25 | enum { |
26 | #define MT_CACHECLEAN 5 | 26 | MT_UNCACHED = 4, |
27 | #define MT_MINICLEAN 6 | 27 | MT_CACHECLEAN, |
28 | #define MT_LOW_VECTORS 7 | 28 | MT_MINICLEAN, |
29 | #define MT_HIGH_VECTORS 8 | 29 | MT_LOW_VECTORS, |
30 | #define MT_MEMORY 9 | 30 | MT_HIGH_VECTORS, |
31 | #define MT_ROM 10 | 31 | MT_MEMORY_RWX, |
32 | #define MT_MEMORY_NONCACHED 11 | 32 | MT_MEMORY_RW, |
33 | #define MT_MEMORY_DTCM 12 | 33 | MT_ROM, |
34 | #define MT_MEMORY_ITCM 13 | 34 | MT_MEMORY_RWX_NONCACHED, |
35 | #define MT_MEMORY_SO 14 | 35 | MT_MEMORY_RW_DTCM, |
36 | #define MT_MEMORY_DMA_READY 15 | 36 | MT_MEMORY_RWX_ITCM, |
37 | MT_MEMORY_RW_SO, | ||
38 | MT_MEMORY_DMA_READY, | ||
39 | }; | ||
37 | 40 | ||
38 | #ifdef CONFIG_MMU | 41 | #ifdef CONFIG_MMU |
39 | extern void iotable_init(struct map_desc *, int); | 42 | extern void iotable_init(struct map_desc *, int); |
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index a98a2e112fae..680a83e94467 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h | |||
@@ -57,12 +57,9 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
57 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 57 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
58 | enum pci_mmap_state mmap_state, int write_combine); | 58 | enum pci_mmap_state mmap_state, int write_combine); |
59 | 59 | ||
60 | /* | ||
61 | * Dummy implementation; always return 0. | ||
62 | */ | ||
63 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | 60 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) |
64 | { | 61 | { |
65 | return 0; | 62 | return channel ? 15 : 14; |
66 | } | 63 | } |
67 | 64 | ||
68 | #endif /* __KERNEL__ */ | 65 | #endif /* __KERNEL__ */ |
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index 86a659a19526..dfff709fda3c 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h | |||
@@ -160,6 +160,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | |||
160 | return (pmd_t *)pud; | 160 | return (pmd_t *)pud; |
161 | } | 161 | } |
162 | 162 | ||
163 | #define pmd_large(pmd) (pmd_val(pmd) & 2) | ||
163 | #define pmd_bad(pmd) (pmd_val(pmd) & 2) | 164 | #define pmd_bad(pmd) (pmd_val(pmd) & 2) |
164 | 165 | ||
165 | #define copy_pmd(pmdpd,pmdps) \ | 166 | #define copy_pmd(pmdpd,pmdps) \ |
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 4f9503908dca..03243f7eeddf 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h | |||
@@ -142,6 +142,7 @@ | |||
142 | PMD_TYPE_TABLE) | 142 | PMD_TYPE_TABLE) |
143 | #define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \ | 143 | #define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \ |
144 | PMD_TYPE_SECT) | 144 | PMD_TYPE_SECT) |
145 | #define pmd_large(pmd) pmd_sect(pmd) | ||
145 | 146 | ||
146 | #define pud_clear(pudp) \ | 147 | #define pud_clear(pudp) \ |
147 | do { \ | 148 | do { \ |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 1571d126e9dd..7d59b524f2af 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -254,6 +254,8 @@ PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); | |||
254 | PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); | 254 | PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); |
255 | PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); | 255 | PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); |
256 | PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); | 256 | PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); |
257 | PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); | ||
258 | PTE_BIT_FUNC(mknexec, |= L_PTE_XN); | ||
257 | 259 | ||
258 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | 260 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } |
259 | 261 | ||
diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h index 4d52f92967a6..a6d0a29861e7 100644 --- a/arch/arm/include/asm/word-at-a-time.h +++ b/arch/arm/include/asm/word-at-a-time.h | |||
@@ -48,10 +48,14 @@ static inline unsigned long find_zero(unsigned long mask) | |||
48 | return ret; | 48 | return ret; |
49 | } | 49 | } |
50 | 50 | ||
51 | #ifdef CONFIG_DCACHE_WORD_ACCESS | ||
52 | |||
53 | #define zero_bytemask(mask) (mask) | 51 | #define zero_bytemask(mask) (mask) |
54 | 52 | ||
53 | #else /* __ARMEB__ */ | ||
54 | #include <asm-generic/word-at-a-time.h> | ||
55 | #endif | ||
56 | |||
57 | #ifdef CONFIG_DCACHE_WORD_ACCESS | ||
58 | |||
55 | /* | 59 | /* |
56 | * Load an unaligned word from kernel space. | 60 | * Load an unaligned word from kernel space. |
57 | * | 61 | * |
@@ -73,7 +77,11 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) | |||
73 | " bic %2, %2, #0x3\n" | 77 | " bic %2, %2, #0x3\n" |
74 | " ldr %0, [%2]\n" | 78 | " ldr %0, [%2]\n" |
75 | " lsl %1, %1, #0x3\n" | 79 | " lsl %1, %1, #0x3\n" |
80 | #ifndef __ARMEB__ | ||
76 | " lsr %0, %0, %1\n" | 81 | " lsr %0, %0, %1\n" |
82 | #else | ||
83 | " lsl %0, %0, %1\n" | ||
84 | #endif | ||
77 | " b 2b\n" | 85 | " b 2b\n" |
78 | " .popsection\n" | 86 | " .popsection\n" |
79 | " .pushsection __ex_table,\"a\"\n" | 87 | " .pushsection __ex_table,\"a\"\n" |
@@ -86,11 +94,5 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) | |||
86 | return ret; | 94 | return ret; |
87 | } | 95 | } |
88 | 96 | ||
89 | |||
90 | #endif /* DCACHE_WORD_ACCESS */ | 97 | #endif /* DCACHE_WORD_ACCESS */ |
91 | |||
92 | #else /* __ARMEB__ */ | ||
93 | #include <asm-generic/word-at-a-time.h> | ||
94 | #endif | ||
95 | |||
96 | #endif /* __ASM_ARM_WORD_AT_A_TIME_H */ | 98 | #endif /* __ASM_ARM_WORD_AT_A_TIME_H */ |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 1f031ddd0667..85e664b6a5f1 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -35,6 +35,8 @@ extern void __ucmpdi2(void); | |||
35 | extern void __udivsi3(void); | 35 | extern void __udivsi3(void); |
36 | extern void __umodsi3(void); | 36 | extern void __umodsi3(void); |
37 | extern void __do_div64(void); | 37 | extern void __do_div64(void); |
38 | extern void __bswapsi2(void); | ||
39 | extern void __bswapdi2(void); | ||
38 | 40 | ||
39 | extern void __aeabi_idiv(void); | 41 | extern void __aeabi_idiv(void); |
40 | extern void __aeabi_idivmod(void); | 42 | extern void __aeabi_idivmod(void); |
@@ -114,6 +116,8 @@ EXPORT_SYMBOL(__ucmpdi2); | |||
114 | EXPORT_SYMBOL(__udivsi3); | 116 | EXPORT_SYMBOL(__udivsi3); |
115 | EXPORT_SYMBOL(__umodsi3); | 117 | EXPORT_SYMBOL(__umodsi3); |
116 | EXPORT_SYMBOL(__do_div64); | 118 | EXPORT_SYMBOL(__do_div64); |
119 | EXPORT_SYMBOL(__bswapsi2); | ||
120 | EXPORT_SYMBOL(__bswapdi2); | ||
117 | 121 | ||
118 | #ifdef CONFIG_AEABI | 122 | #ifdef CONFIG_AEABI |
119 | EXPORT_SYMBOL(__aeabi_idiv); | 123 | EXPORT_SYMBOL(__aeabi_idiv); |
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S index 52b26432c9a9..2260f1855820 100644 --- a/arch/arm/kernel/entry-v7m.S +++ b/arch/arm/kernel/entry-v7m.S | |||
@@ -14,8 +14,6 @@ | |||
14 | #include <asm/thread_notify.h> | 14 | #include <asm/thread_notify.h> |
15 | #include <asm/v7m.h> | 15 | #include <asm/v7m.h> |
16 | 16 | ||
17 | #include <mach/entry-macro.S> | ||
18 | |||
19 | #include "entry-header.S" | 17 | #include "entry-header.S" |
20 | 18 | ||
21 | #ifdef CONFIG_TRACE_IRQFLAGS | 19 | #ifdef CONFIG_TRACE_IRQFLAGS |
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 8ff0ecdc637f..131a6ab5f355 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c | |||
@@ -385,7 +385,6 @@ out: | |||
385 | return ret; | 385 | return ret; |
386 | 386 | ||
387 | out_unmap: | 387 | out_unmap: |
388 | amba_set_drvdata(dev, NULL); | ||
389 | iounmap(t->etb_regs); | 388 | iounmap(t->etb_regs); |
390 | 389 | ||
391 | out_release: | 390 | out_release: |
@@ -398,8 +397,6 @@ static int etb_remove(struct amba_device *dev) | |||
398 | { | 397 | { |
399 | struct tracectx *t = amba_get_drvdata(dev); | 398 | struct tracectx *t = amba_get_drvdata(dev); |
400 | 399 | ||
401 | amba_set_drvdata(dev, NULL); | ||
402 | |||
403 | iounmap(t->etb_regs); | 400 | iounmap(t->etb_regs); |
404 | t->etb_regs = NULL; | 401 | t->etb_regs = NULL; |
405 | 402 | ||
@@ -588,7 +585,6 @@ out: | |||
588 | return ret; | 585 | return ret; |
589 | 586 | ||
590 | out_unmap: | 587 | out_unmap: |
591 | amba_set_drvdata(dev, NULL); | ||
592 | iounmap(t->etm_regs); | 588 | iounmap(t->etm_regs); |
593 | 589 | ||
594 | out_release: | 590 | out_release: |
@@ -601,8 +597,6 @@ static int etm_remove(struct amba_device *dev) | |||
601 | { | 597 | { |
602 | struct tracectx *t = amba_get_drvdata(dev); | 598 | struct tracectx *t = amba_get_drvdata(dev); |
603 | 599 | ||
604 | amba_set_drvdata(dev, NULL); | ||
605 | |||
606 | iounmap(t->etm_regs); | 600 | iounmap(t->etm_regs); |
607 | t->etm_regs = NULL; | 601 | t->etm_regs = NULL; |
608 | 602 | ||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8ce1cbd08dba..1e8b030dbefd 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -334,7 +334,7 @@ static void __init cacheid_init(void) | |||
334 | cacheid = CACHEID_VIVT; | 334 | cacheid = CACHEID_VIVT; |
335 | } | 335 | } |
336 | 336 | ||
337 | printk("CPU: %s data cache, %s instruction cache\n", | 337 | pr_info("CPU: %s data cache, %s instruction cache\n", |
338 | cache_is_vivt() ? "VIVT" : | 338 | cache_is_vivt() ? "VIVT" : |
339 | cache_is_vipt_aliasing() ? "VIPT aliasing" : | 339 | cache_is_vipt_aliasing() ? "VIPT aliasing" : |
340 | cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown", | 340 | cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown", |
@@ -416,7 +416,7 @@ void notrace cpu_init(void) | |||
416 | struct stack *stk = &stacks[cpu]; | 416 | struct stack *stk = &stacks[cpu]; |
417 | 417 | ||
418 | if (cpu >= NR_CPUS) { | 418 | if (cpu >= NR_CPUS) { |
419 | printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); | 419 | pr_crit("CPU%u: bad primary CPU number\n", cpu); |
420 | BUG(); | 420 | BUG(); |
421 | } | 421 | } |
422 | 422 | ||
@@ -484,7 +484,7 @@ void __init smp_setup_processor_id(void) | |||
484 | */ | 484 | */ |
485 | set_my_cpu_offset(0); | 485 | set_my_cpu_offset(0); |
486 | 486 | ||
487 | printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr); | 487 | pr_info("Booting Linux on physical CPU 0x%x\n", mpidr); |
488 | } | 488 | } |
489 | 489 | ||
490 | struct mpidr_hash mpidr_hash; | 490 | struct mpidr_hash mpidr_hash; |
@@ -564,8 +564,8 @@ static void __init setup_processor(void) | |||
564 | */ | 564 | */ |
565 | list = lookup_processor_type(read_cpuid_id()); | 565 | list = lookup_processor_type(read_cpuid_id()); |
566 | if (!list) { | 566 | if (!list) { |
567 | printk("CPU configuration botched (ID %08x), unable " | 567 | pr_err("CPU configuration botched (ID %08x), unable to continue.\n", |
568 | "to continue.\n", read_cpuid_id()); | 568 | read_cpuid_id()); |
569 | while (1); | 569 | while (1); |
570 | } | 570 | } |
571 | 571 | ||
@@ -585,9 +585,9 @@ static void __init setup_processor(void) | |||
585 | cpu_cache = *list->cache; | 585 | cpu_cache = *list->cache; |
586 | #endif | 586 | #endif |
587 | 587 | ||
588 | printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", | 588 | pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", |
589 | cpu_name, read_cpuid_id(), read_cpuid_id() & 15, | 589 | cpu_name, read_cpuid_id(), read_cpuid_id() & 15, |
590 | proc_arch[cpu_architecture()], cr_alignment); | 590 | proc_arch[cpu_architecture()], cr_alignment); |
591 | 591 | ||
592 | snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", | 592 | snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", |
593 | list->arch_name, ENDIANNESS); | 593 | list->arch_name, ENDIANNESS); |
@@ -629,8 +629,8 @@ int __init arm_add_memory(u64 start, u64 size) | |||
629 | u64 aligned_start; | 629 | u64 aligned_start; |
630 | 630 | ||
631 | if (meminfo.nr_banks >= NR_BANKS) { | 631 | if (meminfo.nr_banks >= NR_BANKS) { |
632 | printk(KERN_CRIT "NR_BANKS too low, " | 632 | pr_crit("NR_BANKS too low, ignoring memory at 0x%08llx\n", |
633 | "ignoring memory at 0x%08llx\n", (long long)start); | 633 | (long long)start); |
634 | return -EINVAL; | 634 | return -EINVAL; |
635 | } | 635 | } |
636 | 636 | ||
@@ -643,14 +643,14 @@ int __init arm_add_memory(u64 start, u64 size) | |||
643 | 643 | ||
644 | #ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT | 644 | #ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT |
645 | if (aligned_start > ULONG_MAX) { | 645 | if (aligned_start > ULONG_MAX) { |
646 | printk(KERN_CRIT "Ignoring memory at 0x%08llx outside " | 646 | pr_crit("Ignoring memory at 0x%08llx outside 32-bit physical address space\n", |
647 | "32-bit physical address space\n", (long long)start); | 647 | (long long)start); |
648 | return -EINVAL; | 648 | return -EINVAL; |
649 | } | 649 | } |
650 | 650 | ||
651 | if (aligned_start + size > ULONG_MAX) { | 651 | if (aligned_start + size > ULONG_MAX) { |
652 | printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " | 652 | pr_crit("Truncating memory at 0x%08llx to fit in 32-bit physical address space\n", |
653 | "32-bit physical address space\n", (long long)start); | 653 | (long long)start); |
654 | /* | 654 | /* |
655 | * To ensure bank->start + bank->size is representable in | 655 | * To ensure bank->start + bank->size is representable in |
656 | * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. | 656 | * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. |
@@ -660,6 +660,20 @@ int __init arm_add_memory(u64 start, u64 size) | |||
660 | } | 660 | } |
661 | #endif | 661 | #endif |
662 | 662 | ||
663 | if (aligned_start < PHYS_OFFSET) { | ||
664 | if (aligned_start + size <= PHYS_OFFSET) { | ||
665 | pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n", | ||
666 | aligned_start, aligned_start + size); | ||
667 | return -EINVAL; | ||
668 | } | ||
669 | |||
670 | pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n", | ||
671 | aligned_start, (u64)PHYS_OFFSET); | ||
672 | |||
673 | size -= PHYS_OFFSET - aligned_start; | ||
674 | aligned_start = PHYS_OFFSET; | ||
675 | } | ||
676 | |||
663 | bank->start = aligned_start; | 677 | bank->start = aligned_start; |
664 | bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1); | 678 | bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1); |
665 | 679 | ||
@@ -817,18 +831,17 @@ static void __init reserve_crashkernel(void) | |||
817 | if (ret) | 831 | if (ret) |
818 | return; | 832 | return; |
819 | 833 | ||
820 | ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE); | 834 | ret = memblock_reserve(crash_base, crash_size); |
821 | if (ret < 0) { | 835 | if (ret < 0) { |
822 | printk(KERN_WARNING "crashkernel reservation failed - " | 836 | pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n", |
823 | "memory is in use (0x%lx)\n", (unsigned long)crash_base); | 837 | (unsigned long)crash_base); |
824 | return; | 838 | return; |
825 | } | 839 | } |
826 | 840 | ||
827 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | 841 | pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n", |
828 | "for crashkernel (System RAM: %ldMB)\n", | 842 | (unsigned long)(crash_size >> 20), |
829 | (unsigned long)(crash_size >> 20), | 843 | (unsigned long)(crash_base >> 20), |
830 | (unsigned long)(crash_base >> 20), | 844 | (unsigned long)(total_mem >> 20)); |
831 | (unsigned long)(total_mem >> 20)); | ||
832 | 845 | ||
833 | crashk_res.start = crash_base; | 846 | crashk_res.start = crash_base; |
834 | crashk_res.end = crash_base + crash_size - 1; | 847 | crashk_res.end = crash_base + crash_size - 1; |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index dc894ab3622b..b7b4c86e338b 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -105,8 +105,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) | |||
105 | secondary_data.pgdir = get_arch_pgd(idmap_pgd); | 105 | secondary_data.pgdir = get_arch_pgd(idmap_pgd); |
106 | secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir); | 106 | secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir); |
107 | #endif | 107 | #endif |
108 | __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); | 108 | sync_cache_w(&secondary_data); |
109 | outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); | ||
110 | 109 | ||
111 | /* | 110 | /* |
112 | * Now bring the CPU into our world. | 111 | * Now bring the CPU into our world. |
@@ -294,6 +293,9 @@ void __ref cpu_die(void) | |||
294 | if (smp_ops.cpu_die) | 293 | if (smp_ops.cpu_die) |
295 | smp_ops.cpu_die(cpu); | 294 | smp_ops.cpu_die(cpu); |
296 | 295 | ||
296 | pr_warn("CPU%u: smp_ops.cpu_die() returned, trying to resuscitate\n", | ||
297 | cpu); | ||
298 | |||
297 | /* | 299 | /* |
298 | * Do not return to the idle loop - jump back to the secondary | 300 | * Do not return to the idle loop - jump back to the secondary |
299 | * cpu initialisation. There's some initialisation which needs | 301 | * cpu initialisation. There's some initialisation which needs |
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index f50f19e5c138..7a3be1d4d0b1 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c | |||
@@ -52,7 +52,7 @@ static struct map_desc dtcm_iomap[] __initdata = { | |||
52 | .virtual = DTCM_OFFSET, | 52 | .virtual = DTCM_OFFSET, |
53 | .pfn = __phys_to_pfn(DTCM_OFFSET), | 53 | .pfn = __phys_to_pfn(DTCM_OFFSET), |
54 | .length = 0, | 54 | .length = 0, |
55 | .type = MT_MEMORY_DTCM | 55 | .type = MT_MEMORY_RW_DTCM |
56 | } | 56 | } |
57 | }; | 57 | }; |
58 | 58 | ||
@@ -61,7 +61,7 @@ static struct map_desc itcm_iomap[] __initdata = { | |||
61 | .virtual = ITCM_OFFSET, | 61 | .virtual = ITCM_OFFSET, |
62 | .pfn = __phys_to_pfn(ITCM_OFFSET), | 62 | .pfn = __phys_to_pfn(ITCM_OFFSET), |
63 | .length = 0, | 63 | .length = 0, |
64 | .type = MT_MEMORY_ITCM | 64 | .type = MT_MEMORY_RWX_ITCM, |
65 | } | 65 | } |
66 | }; | 66 | }; |
67 | 67 | ||
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 85a87370f144..0bc94b1fd1ae 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
@@ -68,16 +68,16 @@ struct cpu_efficiency { | |||
68 | * Processors that are not defined in the table, | 68 | * Processors that are not defined in the table, |
69 | * use the default SCHED_POWER_SCALE value for cpu_scale. | 69 | * use the default SCHED_POWER_SCALE value for cpu_scale. |
70 | */ | 70 | */ |
71 | struct cpu_efficiency table_efficiency[] = { | 71 | static const struct cpu_efficiency table_efficiency[] = { |
72 | {"arm,cortex-a15", 3891}, | 72 | {"arm,cortex-a15", 3891}, |
73 | {"arm,cortex-a7", 2048}, | 73 | {"arm,cortex-a7", 2048}, |
74 | {NULL, }, | 74 | {NULL, }, |
75 | }; | 75 | }; |
76 | 76 | ||
77 | unsigned long *__cpu_capacity; | 77 | static unsigned long *__cpu_capacity; |
78 | #define cpu_capacity(cpu) __cpu_capacity[cpu] | 78 | #define cpu_capacity(cpu) __cpu_capacity[cpu] |
79 | 79 | ||
80 | unsigned long middle_capacity = 1; | 80 | static unsigned long middle_capacity = 1; |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * Iterate all CPUs' descriptor in DT and compute the efficiency | 83 | * Iterate all CPUs' descriptor in DT and compute the efficiency |
@@ -89,7 +89,7 @@ unsigned long middle_capacity = 1; | |||
89 | */ | 89 | */ |
90 | static void __init parse_dt_topology(void) | 90 | static void __init parse_dt_topology(void) |
91 | { | 91 | { |
92 | struct cpu_efficiency *cpu_eff; | 92 | const struct cpu_efficiency *cpu_eff; |
93 | struct device_node *cn = NULL; | 93 | struct device_node *cn = NULL; |
94 | unsigned long min_capacity = (unsigned long)(-1); | 94 | unsigned long min_capacity = (unsigned long)(-1); |
95 | unsigned long max_capacity = 0; | 95 | unsigned long max_capacity = 0; |
@@ -158,7 +158,7 @@ static void __init parse_dt_topology(void) | |||
158 | * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the | 158 | * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the |
159 | * function returns directly for SMP system. | 159 | * function returns directly for SMP system. |
160 | */ | 160 | */ |
161 | void update_cpu_power(unsigned int cpu) | 161 | static void update_cpu_power(unsigned int cpu) |
162 | { | 162 | { |
163 | if (!cpu_capacity(cpu)) | 163 | if (!cpu_capacity(cpu)) |
164 | return; | 164 | return; |
@@ -185,7 +185,7 @@ const struct cpumask *cpu_coregroup_mask(int cpu) | |||
185 | return &cpu_topology[cpu].core_sibling; | 185 | return &cpu_topology[cpu].core_sibling; |
186 | } | 186 | } |
187 | 187 | ||
188 | void update_siblings_masks(unsigned int cpuid) | 188 | static void update_siblings_masks(unsigned int cpuid) |
189 | { | 189 | { |
190 | struct cputopo_arm *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; | 190 | struct cputopo_arm *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; |
191 | int cpu; | 191 | int cpu; |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 4636d56af2db..172ee18ff124 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -62,7 +62,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long); | |||
62 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) | 62 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) |
63 | { | 63 | { |
64 | #ifdef CONFIG_KALLSYMS | 64 | #ifdef CONFIG_KALLSYMS |
65 | printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); | 65 | printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); |
66 | #else | 66 | #else |
67 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); | 67 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); |
68 | #endif | 68 | #endif |
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 47d7338561de..0573faab96ad 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile | |||
@@ -13,7 +13,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ | |||
13 | ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ | 13 | ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ |
14 | ucmpdi2.o lib1funcs.o div64.o \ | 14 | ucmpdi2.o lib1funcs.o div64.o \ |
15 | io-readsb.o io-writesb.o io-readsl.o io-writesl.o \ | 15 | io-readsb.o io-writesb.o io-readsl.o io-writesl.o \ |
16 | call_with_stack.o | 16 | call_with_stack.o bswapsdi2.o |
17 | 17 | ||
18 | mmu-y := clear_user.o copy_page.o getuser.o putuser.o | 18 | mmu-y := clear_user.o copy_page.o getuser.o putuser.o |
19 | 19 | ||
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index cd07b5814c23..4102be617fce 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S | |||
@@ -80,14 +80,14 @@ for_each_frame: tst frame, mask @ Check for address exceptions | |||
80 | 80 | ||
81 | ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists, | 81 | ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists, |
82 | ldr r3, .Ldsi+4 | 82 | ldr r3, .Ldsi+4 |
83 | teq r3, r1, lsr #10 | 83 | teq r3, r1, lsr #11 |
84 | ldreq r0, [frame, #-8] @ get sp | 84 | ldreq r0, [frame, #-8] @ get sp |
85 | subeq r0, r0, #4 @ point at the last arg | 85 | subeq r0, r0, #4 @ point at the last arg |
86 | bleq .Ldumpstm @ dump saved registers | 86 | bleq .Ldumpstm @ dump saved registers |
87 | 87 | ||
88 | 1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc} | 88 | 1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc} |
89 | ldr r3, .Ldsi @ instruction exists, | 89 | ldr r3, .Ldsi @ instruction exists, |
90 | teq r3, r1, lsr #10 | 90 | teq r3, r1, lsr #11 |
91 | subeq r0, frame, #16 | 91 | subeq r0, frame, #16 |
92 | bleq .Ldumpstm @ dump saved registers | 92 | bleq .Ldumpstm @ dump saved registers |
93 | 93 | ||
@@ -128,11 +128,11 @@ ENDPROC(c_backtrace) | |||
128 | beq 2f | 128 | beq 2f |
129 | add r7, r7, #1 | 129 | add r7, r7, #1 |
130 | teq r7, #6 | 130 | teq r7, #6 |
131 | moveq r7, #1 | 131 | moveq r7, #0 |
132 | moveq r1, #'\n' | 132 | adr r3, .Lcr |
133 | movne r1, #' ' | 133 | addne r3, r3, #1 @ skip newline |
134 | ldr r3, [stack], #-4 | 134 | ldr r2, [stack], #-4 |
135 | mov r2, reg | 135 | mov r1, reg |
136 | adr r0, .Lfp | 136 | adr r0, .Lfp |
137 | bl printk | 137 | bl printk |
138 | 2: subs reg, reg, #1 | 138 | 2: subs reg, reg, #1 |
@@ -142,11 +142,11 @@ ENDPROC(c_backtrace) | |||
142 | blne printk | 142 | blne printk |
143 | ldmfd sp!, {instr, reg, stack, r7, pc} | 143 | ldmfd sp!, {instr, reg, stack, r7, pc} |
144 | 144 | ||
145 | .Lfp: .asciz "%cr%d:%08x" | 145 | .Lfp: .asciz " r%d:%08x%s" |
146 | .Lcr: .asciz "\n" | 146 | .Lcr: .asciz "\n" |
147 | .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" | 147 | .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" |
148 | .align | 148 | .align |
149 | .Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc} | 149 | .Ldsi: .word 0xe92dd800 >> 11 @ stmfd sp!, {... fp, ip, lr, pc} |
150 | .word 0xe92d0000 >> 10 @ stmfd sp!, {} | 150 | .word 0xe92d0000 >> 11 @ stmfd sp!, {} |
151 | 151 | ||
152 | #endif | 152 | #endif |
diff --git a/arch/arm/lib/bswapsdi2.S b/arch/arm/lib/bswapsdi2.S new file mode 100644 index 000000000000..9fcdd154eff9 --- /dev/null +++ b/arch/arm/lib/bswapsdi2.S | |||
@@ -0,0 +1,36 @@ | |||
1 | #include <linux/linkage.h> | ||
2 | |||
3 | #if __LINUX_ARM_ARCH__ >= 6 | ||
4 | ENTRY(__bswapsi2) | ||
5 | rev r0, r0 | ||
6 | bx lr | ||
7 | ENDPROC(__bswapsi2) | ||
8 | |||
9 | ENTRY(__bswapdi2) | ||
10 | rev r3, r0 | ||
11 | rev r0, r1 | ||
12 | mov r1, r3 | ||
13 | bx lr | ||
14 | ENDPROC(__bswapdi2) | ||
15 | #else | ||
16 | ENTRY(__bswapsi2) | ||
17 | eor r3, r0, r0, ror #16 | ||
18 | mov r3, r3, lsr #8 | ||
19 | bic r3, r3, #0xff00 | ||
20 | eor r0, r3, r0, ror #8 | ||
21 | mov pc, lr | ||
22 | ENDPROC(__bswapsi2) | ||
23 | |||
24 | ENTRY(__bswapdi2) | ||
25 | mov ip, r1 | ||
26 | eor r3, ip, ip, ror #16 | ||
27 | eor r1, r0, r0, ror #16 | ||
28 | mov r1, r1, lsr #8 | ||
29 | mov r3, r3, lsr #8 | ||
30 | bic r3, r3, #0xff00 | ||
31 | bic r1, r1, #0xff00 | ||
32 | eor r1, r1, r0, ror #8 | ||
33 | eor r0, r3, ip, ror #8 | ||
34 | mov pc, lr | ||
35 | ENDPROC(__bswapdi2) | ||
36 | #endif | ||
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 094b3459c288..2742e00ec5d6 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c | |||
@@ -81,7 +81,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length) | |||
81 | 81 | ||
82 | desc->pfn = __phys_to_pfn(base); | 82 | desc->pfn = __phys_to_pfn(base); |
83 | desc->length = length; | 83 | desc->length = length; |
84 | desc->type = MT_MEMORY_NONCACHED; | 84 | desc->type = MT_MEMORY_RWX_NONCACHED; |
85 | 85 | ||
86 | pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", | 86 | pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", |
87 | base, length, desc->virtual); | 87 | base, length, desc->virtual); |
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index e0091685fd48..9e8220e38398 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c | |||
@@ -143,11 +143,6 @@ static struct map_desc fb_common_io_desc[] __initdata = { | |||
143 | .pfn = __phys_to_pfn(DC21285_ARMCSR_BASE), | 143 | .pfn = __phys_to_pfn(DC21285_ARMCSR_BASE), |
144 | .length = ARMCSR_SIZE, | 144 | .length = ARMCSR_SIZE, |
145 | .type = MT_DEVICE, | 145 | .type = MT_DEVICE, |
146 | }, { | ||
147 | .virtual = XBUS_BASE, | ||
148 | .pfn = __phys_to_pfn(0x40000000), | ||
149 | .length = XBUS_SIZE, | ||
150 | .type = MT_DEVICE, | ||
151 | } | 146 | } |
152 | }; | 147 | }; |
153 | 148 | ||
diff --git a/arch/arm/mach-footbridge/common.h b/arch/arm/mach-footbridge/common.h index 56607b3a773e..b911e5587ecf 100644 --- a/arch/arm/mach-footbridge/common.h +++ b/arch/arm/mach-footbridge/common.h | |||
@@ -10,3 +10,5 @@ extern void footbridge_init_irq(void); | |||
10 | 10 | ||
11 | extern void isa_init_irq(unsigned int irq); | 11 | extern void isa_init_irq(unsigned int irq); |
12 | extern void footbridge_restart(enum reboot_mode, const char *); | 12 | extern void footbridge_restart(enum reboot_mode, const char *); |
13 | |||
14 | extern void footbridge_sched_clock(void); | ||
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index 782f6c71fa0a..3971104d32d4 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <linux/sched_clock.h> | ||
12 | 13 | ||
13 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
14 | 15 | ||
@@ -46,6 +47,16 @@ static struct clocksource cksrc_dc21285 = { | |||
46 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 47 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
47 | }; | 48 | }; |
48 | 49 | ||
50 | static int ckevt_dc21285_set_next_event(unsigned long delta, | ||
51 | struct clock_event_device *c) | ||
52 | { | ||
53 | *CSR_TIMER1_CLR = 0; | ||
54 | *CSR_TIMER1_LOAD = delta; | ||
55 | *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16; | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
49 | static void ckevt_dc21285_set_mode(enum clock_event_mode mode, | 60 | static void ckevt_dc21285_set_mode(enum clock_event_mode mode, |
50 | struct clock_event_device *c) | 61 | struct clock_event_device *c) |
51 | { | 62 | { |
@@ -58,7 +69,9 @@ static void ckevt_dc21285_set_mode(enum clock_event_mode mode, | |||
58 | TIMER_CNTL_DIV16; | 69 | TIMER_CNTL_DIV16; |
59 | break; | 70 | break; |
60 | 71 | ||
61 | default: | 72 | case CLOCK_EVT_MODE_ONESHOT: |
73 | case CLOCK_EVT_MODE_UNUSED: | ||
74 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
62 | *CSR_TIMER1_CNTL = 0; | 75 | *CSR_TIMER1_CNTL = 0; |
63 | break; | 76 | break; |
64 | } | 77 | } |
@@ -66,9 +79,11 @@ static void ckevt_dc21285_set_mode(enum clock_event_mode mode, | |||
66 | 79 | ||
67 | static struct clock_event_device ckevt_dc21285 = { | 80 | static struct clock_event_device ckevt_dc21285 = { |
68 | .name = "dc21285_timer1", | 81 | .name = "dc21285_timer1", |
69 | .features = CLOCK_EVT_FEAT_PERIODIC, | 82 | .features = CLOCK_EVT_FEAT_PERIODIC | |
83 | CLOCK_EVT_FEAT_ONESHOT, | ||
70 | .rating = 200, | 84 | .rating = 200, |
71 | .irq = IRQ_TIMER1, | 85 | .irq = IRQ_TIMER1, |
86 | .set_next_event = ckevt_dc21285_set_next_event, | ||
72 | .set_mode = ckevt_dc21285_set_mode, | 87 | .set_mode = ckevt_dc21285_set_mode, |
73 | }; | 88 | }; |
74 | 89 | ||
@@ -78,6 +93,10 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) | |||
78 | 93 | ||
79 | *CSR_TIMER1_CLR = 0; | 94 | *CSR_TIMER1_CLR = 0; |
80 | 95 | ||
96 | /* Stop the timer if in one-shot mode */ | ||
97 | if (ce->mode == CLOCK_EVT_MODE_ONESHOT) | ||
98 | *CSR_TIMER1_CNTL = 0; | ||
99 | |||
81 | ce->event_handler(ce); | 100 | ce->event_handler(ce); |
82 | 101 | ||
83 | return IRQ_HANDLED; | 102 | return IRQ_HANDLED; |
@@ -105,3 +124,19 @@ void __init footbridge_timer_init(void) | |||
105 | ce->cpumask = cpumask_of(smp_processor_id()); | 124 | ce->cpumask = cpumask_of(smp_processor_id()); |
106 | clockevents_config_and_register(ce, rate, 0x4, 0xffffff); | 125 | clockevents_config_and_register(ce, rate, 0x4, 0xffffff); |
107 | } | 126 | } |
127 | |||
128 | static u32 notrace footbridge_read_sched_clock(void) | ||
129 | { | ||
130 | return ~*CSR_TIMER3_VALUE; | ||
131 | } | ||
132 | |||
133 | void __init footbridge_sched_clock(void) | ||
134 | { | ||
135 | unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16); | ||
136 | |||
137 | *CSR_TIMER3_LOAD = 0; | ||
138 | *CSR_TIMER3_CLR = 0; | ||
139 | *CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16; | ||
140 | |||
141 | setup_sched_clock(footbridge_read_sched_clock, 24, rate); | ||
142 | } | ||
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index 1a7235fb52ac..aee8300f3490 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * EBSA285 machine fixup | 4 | * EBSA285 machine fixup |
5 | */ | 5 | */ |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/io.h> | ||
7 | #include <linux/spinlock.h> | 8 | #include <linux/spinlock.h> |
8 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
9 | #include <linux/leds.h> | 10 | #include <linux/leds.h> |
@@ -17,6 +18,11 @@ | |||
17 | 18 | ||
18 | /* LEDs */ | 19 | /* LEDs */ |
19 | #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) | 20 | #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) |
21 | #define XBUS_AMBER_L BIT(0) | ||
22 | #define XBUS_GREEN_L BIT(1) | ||
23 | #define XBUS_RED_L BIT(2) | ||
24 | #define XBUS_TOGGLE BIT(7) | ||
25 | |||
20 | struct ebsa285_led { | 26 | struct ebsa285_led { |
21 | struct led_classdev cdev; | 27 | struct led_classdev cdev; |
22 | u8 mask; | 28 | u8 mask; |
@@ -36,6 +42,7 @@ static const struct { | |||
36 | }; | 42 | }; |
37 | 43 | ||
38 | static unsigned char hw_led_state; | 44 | static unsigned char hw_led_state; |
45 | static void __iomem *xbus; | ||
39 | 46 | ||
40 | static void ebsa285_led_set(struct led_classdev *cdev, | 47 | static void ebsa285_led_set(struct led_classdev *cdev, |
41 | enum led_brightness b) | 48 | enum led_brightness b) |
@@ -47,7 +54,7 @@ static void ebsa285_led_set(struct led_classdev *cdev, | |||
47 | hw_led_state |= led->mask; | 54 | hw_led_state |= led->mask; |
48 | else | 55 | else |
49 | hw_led_state &= ~led->mask; | 56 | hw_led_state &= ~led->mask; |
50 | *XBUS_LEDS = hw_led_state; | 57 | writeb(hw_led_state, xbus); |
51 | } | 58 | } |
52 | 59 | ||
53 | static enum led_brightness ebsa285_led_get(struct led_classdev *cdev) | 60 | static enum led_brightness ebsa285_led_get(struct led_classdev *cdev) |
@@ -65,9 +72,13 @@ static int __init ebsa285_leds_init(void) | |||
65 | if (!machine_is_ebsa285()) | 72 | if (!machine_is_ebsa285()) |
66 | return -ENODEV; | 73 | return -ENODEV; |
67 | 74 | ||
75 | xbus = ioremap(XBUS_CS2, SZ_4K); | ||
76 | if (!xbus) | ||
77 | return -ENOMEM; | ||
78 | |||
68 | /* 3 LEDS all off */ | 79 | /* 3 LEDS all off */ |
69 | hw_led_state = XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED; | 80 | hw_led_state = XBUS_AMBER_L | XBUS_GREEN_L | XBUS_RED_L; |
70 | *XBUS_LEDS = hw_led_state; | 81 | writeb(hw_led_state, xbus); |
71 | 82 | ||
72 | for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) { | 83 | for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) { |
73 | struct ebsa285_led *led; | 84 | struct ebsa285_led *led; |
@@ -104,6 +115,7 @@ MACHINE_START(EBSA285, "EBSA285") | |||
104 | .video_start = 0x000a0000, | 115 | .video_start = 0x000a0000, |
105 | .video_end = 0x000bffff, | 116 | .video_end = 0x000bffff, |
106 | .map_io = footbridge_map_io, | 117 | .map_io = footbridge_map_io, |
118 | .init_early = footbridge_sched_clock, | ||
107 | .init_irq = footbridge_init_irq, | 119 | .init_irq = footbridge_init_irq, |
108 | .init_time = footbridge_timer_init, | 120 | .init_time = footbridge_timer_init, |
109 | .restart = footbridge_restart, | 121 | .restart = footbridge_restart, |
diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h index e3d6ccac2162..02f6d7a706b1 100644 --- a/arch/arm/mach-footbridge/include/mach/hardware.h +++ b/arch/arm/mach-footbridge/include/mach/hardware.h | |||
@@ -51,11 +51,7 @@ | |||
51 | #define PCIMEM_SIZE 0x01000000 | 51 | #define PCIMEM_SIZE 0x01000000 |
52 | #define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000) | 52 | #define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000) |
53 | 53 | ||
54 | #define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000)) | 54 | #define XBUS_CS2 0x40012000 |
55 | #define XBUS_LED_AMBER (1 << 0) | ||
56 | #define XBUS_LED_GREEN (1 << 1) | ||
57 | #define XBUS_LED_RED (1 << 2) | ||
58 | #define XBUS_LED_TOGGLE (1 << 8) | ||
59 | 55 | ||
60 | #define XBUS_SWITCH ((volatile unsigned char *)(XBUS_BASE + 0x12000)) | 56 | #define XBUS_SWITCH ((volatile unsigned char *)(XBUS_BASE + 0x12000)) |
61 | #define XBUS_SWITCH_SWITCH ((*XBUS_SWITCH) & 15) | 57 | #define XBUS_SWITCH_SWITCH ((*XBUS_SWITCH) & 15) |
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 7a6e6f710068..fae0578fec7e 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -3,7 +3,6 @@ config ARCH_MXC | |||
3 | select ARCH_REQUIRE_GPIOLIB | 3 | select ARCH_REQUIRE_GPIOLIB |
4 | select ARM_CPU_SUSPEND if PM | 4 | select ARM_CPU_SUSPEND if PM |
5 | select ARM_PATCH_PHYS_VIRT | 5 | select ARM_PATCH_PHYS_VIRT |
6 | select AUTO_ZRELADDR if !ZBOOT_ROM | ||
7 | select CLKSRC_MMIO | 6 | select CLKSRC_MMIO |
8 | select COMMON_CLK | 7 | select COMMON_CLK |
9 | select GENERIC_ALLOCATOR | 8 | select GENERIC_ALLOCATOR |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index cd22262a2cc0..07b68d5a7940 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -244,7 +244,7 @@ static struct map_desc omap44xx_io_desc[] __initdata = { | |||
244 | .virtual = OMAP4_SRAM_VA, | 244 | .virtual = OMAP4_SRAM_VA, |
245 | .pfn = __phys_to_pfn(OMAP4_SRAM_PA), | 245 | .pfn = __phys_to_pfn(OMAP4_SRAM_PA), |
246 | .length = PAGE_SIZE, | 246 | .length = PAGE_SIZE, |
247 | .type = MT_MEMORY_SO, | 247 | .type = MT_MEMORY_RW_SO, |
248 | }, | 248 | }, |
249 | #endif | 249 | #endif |
250 | 250 | ||
@@ -282,7 +282,7 @@ static struct map_desc omap54xx_io_desc[] __initdata = { | |||
282 | .virtual = OMAP4_SRAM_VA, | 282 | .virtual = OMAP4_SRAM_VA, |
283 | .pfn = __phys_to_pfn(OMAP4_SRAM_PA), | 283 | .pfn = __phys_to_pfn(OMAP4_SRAM_PA), |
284 | .length = PAGE_SIZE, | 284 | .length = PAGE_SIZE, |
285 | .type = MT_MEMORY_SO, | 285 | .type = MT_MEMORY_RW_SO, |
286 | }, | 286 | }, |
287 | #endif | 287 | #endif |
288 | }; | 288 | }; |
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index c0ab9b26be3d..dd893ec4c8f2 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -87,7 +87,7 @@ void __init omap_barriers_init(void) | |||
87 | dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; | 87 | dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; |
88 | dram_io_desc[0].pfn = __phys_to_pfn(paddr); | 88 | dram_io_desc[0].pfn = __phys_to_pfn(paddr); |
89 | dram_io_desc[0].length = size; | 89 | dram_io_desc[0].length = size; |
90 | dram_io_desc[0].type = MT_MEMORY_SO; | 90 | dram_io_desc[0].type = MT_MEMORY_RW_SO; |
91 | iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); | 91 | iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); |
92 | dram_sync = (void __iomem *) dram_io_desc[0].virtual; | 92 | dram_sync = (void __iomem *) dram_io_desc[0].virtual; |
93 | sram_sync = (void __iomem *) OMAP4_SRAM_VA; | 93 | sram_sync = (void __iomem *) OMAP4_SRAM_VA; |
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index c9808c684152..8443a27bca2f 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c | |||
@@ -75,12 +75,143 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val) | |||
75 | 75 | ||
76 | EXPORT_SYMBOL(ASSABET_BCR_frob); | 76 | EXPORT_SYMBOL(ASSABET_BCR_frob); |
77 | 77 | ||
78 | /* | ||
79 | * The codec reset goes to three devices, so we need to release | ||
80 | * the rest when any one of these requests it. However, that | ||
81 | * causes the ADV7171 to consume around 100mA - more than half | ||
82 | * the LCD-blanked power. | ||
83 | * | ||
84 | * With the ADV7171, LCD and backlight enabled, we go over | ||
85 | * budget on the MAX846 Li-Ion charger, and if no Li-Ion battery | ||
86 | * is connected, the Assabet crashes. | ||
87 | */ | ||
88 | #define RST_UCB1X00 (1 << 0) | ||
89 | #define RST_UDA1341 (1 << 1) | ||
90 | #define RST_ADV7171 (1 << 2) | ||
91 | |||
92 | #define SDA GPIO_GPIO(15) | ||
93 | #define SCK GPIO_GPIO(18) | ||
94 | #define MOD GPIO_GPIO(17) | ||
95 | |||
96 | static void adv7171_start(void) | ||
97 | { | ||
98 | GPSR = SCK; | ||
99 | udelay(1); | ||
100 | GPSR = SDA; | ||
101 | udelay(2); | ||
102 | GPCR = SDA; | ||
103 | } | ||
104 | |||
105 | static void adv7171_stop(void) | ||
106 | { | ||
107 | GPSR = SCK; | ||
108 | udelay(2); | ||
109 | GPSR = SDA; | ||
110 | udelay(1); | ||
111 | } | ||
112 | |||
113 | static void adv7171_send(unsigned byte) | ||
114 | { | ||
115 | unsigned i; | ||
116 | |||
117 | for (i = 0; i < 8; i++, byte <<= 1) { | ||
118 | GPCR = SCK; | ||
119 | udelay(1); | ||
120 | if (byte & 0x80) | ||
121 | GPSR = SDA; | ||
122 | else | ||
123 | GPCR = SDA; | ||
124 | udelay(1); | ||
125 | GPSR = SCK; | ||
126 | udelay(1); | ||
127 | } | ||
128 | GPCR = SCK; | ||
129 | udelay(1); | ||
130 | GPSR = SDA; | ||
131 | udelay(1); | ||
132 | GPDR &= ~SDA; | ||
133 | GPSR = SCK; | ||
134 | udelay(1); | ||
135 | if (GPLR & SDA) | ||
136 | printk(KERN_WARNING "No ACK from ADV7171\n"); | ||
137 | udelay(1); | ||
138 | GPCR = SCK | SDA; | ||
139 | udelay(1); | ||
140 | GPDR |= SDA; | ||
141 | udelay(1); | ||
142 | } | ||
143 | |||
144 | static void adv7171_write(unsigned reg, unsigned val) | ||
145 | { | ||
146 | unsigned gpdr = GPDR; | ||
147 | unsigned gplr = GPLR; | ||
148 | |||
149 | ASSABET_BCR = BCR_value | ASSABET_BCR_AUDIO_ON; | ||
150 | udelay(100); | ||
151 | |||
152 | GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */ | ||
153 | GPDR = (GPDR | SCK | MOD) & ~SDA; | ||
154 | udelay(10); | ||
155 | if (!(GPLR & SDA)) | ||
156 | printk(KERN_WARNING "Something dragging SDA down?\n"); | ||
157 | GPDR |= SDA; | ||
158 | |||
159 | adv7171_start(); | ||
160 | adv7171_send(0x54); | ||
161 | adv7171_send(reg); | ||
162 | adv7171_send(val); | ||
163 | adv7171_stop(); | ||
164 | |||
165 | /* Restore GPIO state for L3 bus */ | ||
166 | GPSR = gplr & (SDA | SCK | MOD); | ||
167 | GPCR = (~gplr) & (SDA | SCK | MOD); | ||
168 | GPDR = gpdr; | ||
169 | } | ||
170 | |||
171 | static void adv7171_sleep(void) | ||
172 | { | ||
173 | /* Put the ADV7171 into sleep mode */ | ||
174 | adv7171_write(0x04, 0x40); | ||
175 | } | ||
176 | |||
177 | static unsigned codec_nreset; | ||
178 | |||
179 | static void assabet_codec_reset(unsigned mask, int set) | ||
180 | { | ||
181 | unsigned long flags; | ||
182 | bool old; | ||
183 | |||
184 | local_irq_save(flags); | ||
185 | old = !codec_nreset; | ||
186 | if (set) | ||
187 | codec_nreset &= ~mask; | ||
188 | else | ||
189 | codec_nreset |= mask; | ||
190 | |||
191 | if (old != !codec_nreset) { | ||
192 | if (codec_nreset) { | ||
193 | ASSABET_BCR_set(ASSABET_BCR_NCODEC_RST); | ||
194 | adv7171_sleep(); | ||
195 | } else { | ||
196 | ASSABET_BCR_clear(ASSABET_BCR_NCODEC_RST); | ||
197 | } | ||
198 | } | ||
199 | local_irq_restore(flags); | ||
200 | } | ||
201 | |||
78 | static void assabet_ucb1x00_reset(enum ucb1x00_reset state) | 202 | static void assabet_ucb1x00_reset(enum ucb1x00_reset state) |
79 | { | 203 | { |
80 | if (state == UCB_RST_PROBE) | 204 | int set = state == UCB_RST_REMOVE || state == UCB_RST_SUSPEND || |
81 | ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); | 205 | state == UCB_RST_PROBE_FAIL; |
206 | assabet_codec_reset(RST_UCB1X00, set); | ||
82 | } | 207 | } |
83 | 208 | ||
209 | void assabet_uda1341_reset(int set) | ||
210 | { | ||
211 | assabet_codec_reset(RST_UDA1341, set); | ||
212 | } | ||
213 | EXPORT_SYMBOL(assabet_uda1341_reset); | ||
214 | |||
84 | 215 | ||
85 | /* | 216 | /* |
86 | * Assabet flash support code. | 217 | * Assabet flash support code. |
@@ -155,12 +286,9 @@ static int assabet_irda_set_power(struct device *dev, unsigned int state) | |||
155 | 0 | 286 | 0 |
156 | }; | 287 | }; |
157 | 288 | ||
158 | if (state < 4) { | 289 | if (state < 4) |
159 | state = bcr_state[state]; | 290 | ASSABET_BCR_frob(ASSABET_BCR_IRDA_MD1 | ASSABET_BCR_IRDA_MD0, |
160 | ASSABET_BCR_clear(state ^ (ASSABET_BCR_IRDA_MD1| | 291 | bcr_state[state]); |
161 | ASSABET_BCR_IRDA_MD0)); | ||
162 | ASSABET_BCR_set(state); | ||
163 | } | ||
164 | return 0; | 292 | return 0; |
165 | } | 293 | } |
166 | 294 | ||
@@ -180,6 +308,7 @@ static struct irda_platform_data assabet_irda_data = { | |||
180 | static struct ucb1x00_plat_data assabet_ucb1x00_data = { | 308 | static struct ucb1x00_plat_data assabet_ucb1x00_data = { |
181 | .reset = assabet_ucb1x00_reset, | 309 | .reset = assabet_ucb1x00_reset, |
182 | .gpio_base = -1, | 310 | .gpio_base = -1, |
311 | .can_wakeup = 1, | ||
183 | }; | 312 | }; |
184 | 313 | ||
185 | static struct mcp_plat_data assabet_mcp_data = { | 314 | static struct mcp_plat_data assabet_mcp_data = { |
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 7fb96ebdc0fb..831a15824ec8 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mtd/mtd.h> | 27 | #include <linux/mtd/mtd.h> |
28 | #include <linux/mtd/partitions.h> | 28 | #include <linux/mtd/partitions.h> |
29 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
30 | #include <linux/gpio_keys.h> | ||
31 | #include <linux/input.h> | ||
30 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
31 | #include <linux/pda_power.h> | 33 | #include <linux/pda_power.h> |
32 | 34 | ||
@@ -242,10 +244,43 @@ struct platform_device collie_locomo_device = { | |||
242 | .resource = locomo_resources, | 244 | .resource = locomo_resources, |
243 | }; | 245 | }; |
244 | 246 | ||
247 | static struct gpio_keys_button collie_gpio_keys[] = { | ||
248 | { | ||
249 | .type = EV_PWR, | ||
250 | .code = KEY_RESERVED, | ||
251 | .gpio = COLLIE_GPIO_ON_KEY, | ||
252 | .desc = "On key", | ||
253 | .wakeup = 1, | ||
254 | .active_low = 1, | ||
255 | }, | ||
256 | { | ||
257 | .type = EV_PWR, | ||
258 | .code = KEY_WAKEUP, | ||
259 | .gpio = COLLIE_GPIO_WAKEUP, | ||
260 | .desc = "Sync", | ||
261 | .wakeup = 1, | ||
262 | .active_low = 1, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | static struct gpio_keys_platform_data collie_gpio_keys_data = { | ||
267 | .buttons = collie_gpio_keys, | ||
268 | .nbuttons = ARRAY_SIZE(collie_gpio_keys), | ||
269 | }; | ||
270 | |||
271 | static struct platform_device collie_gpio_keys_device = { | ||
272 | .name = "gpio-keys", | ||
273 | .id = -1, | ||
274 | .dev = { | ||
275 | .platform_data = &collie_gpio_keys_data, | ||
276 | }, | ||
277 | }; | ||
278 | |||
245 | static struct platform_device *devices[] __initdata = { | 279 | static struct platform_device *devices[] __initdata = { |
246 | &collie_locomo_device, | 280 | &collie_locomo_device, |
247 | &colliescoop_device, | 281 | &colliescoop_device, |
248 | &collie_power_device, | 282 | &collie_power_device, |
283 | &collie_gpio_keys_device, | ||
249 | }; | 284 | }; |
250 | 285 | ||
251 | static struct mtd_partition collie_partitions[] = { | 286 | static struct mtd_partition collie_partitions[] = { |
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c index b8f2b151539b..daa27c474c13 100644 --- a/arch/arm/mach-sa1100/h3100.c +++ b/arch/arm/mach-sa1100/h3100.c | |||
@@ -28,15 +28,35 @@ | |||
28 | /* | 28 | /* |
29 | * helper for sa1100fb | 29 | * helper for sa1100fb |
30 | */ | 30 | */ |
31 | static struct gpio h3100_lcd_gpio[] = { | ||
32 | { H3100_GPIO_LCD_3V_ON, GPIOF_OUT_INIT_LOW, "LCD 3V" }, | ||
33 | { H3XXX_EGPIO_LCD_ON, GPIOF_OUT_INIT_LOW, "LCD ON" }, | ||
34 | }; | ||
35 | |||
36 | static bool h3100_lcd_request(void) | ||
37 | { | ||
38 | static bool h3100_lcd_ok; | ||
39 | int rc; | ||
40 | |||
41 | if (h3100_lcd_ok) | ||
42 | return true; | ||
43 | |||
44 | rc = gpio_request_array(h3100_lcd_gpio, ARRAY_SIZE(h3100_lcd_gpio)); | ||
45 | if (rc) | ||
46 | pr_err("%s: can't request GPIOs\n", __func__); | ||
47 | else | ||
48 | h3100_lcd_ok = true; | ||
49 | |||
50 | return h3100_lcd_ok; | ||
51 | } | ||
52 | |||
31 | static void h3100_lcd_power(int enable) | 53 | static void h3100_lcd_power(int enable) |
32 | { | 54 | { |
33 | if (!gpio_request(H3XXX_EGPIO_LCD_ON, "LCD ON")) { | 55 | if (!h3100_lcd_request()) |
34 | gpio_set_value(H3100_GPIO_LCD_3V_ON, enable); | 56 | return; |
35 | gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable); | 57 | |
36 | gpio_free(H3XXX_EGPIO_LCD_ON); | 58 | gpio_set_value(H3100_GPIO_LCD_3V_ON, enable); |
37 | } else { | 59 | gpio_set_value(H3XXX_EGPIO_LCD_ON, enable); |
38 | pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__); | ||
39 | } | ||
40 | } | 60 | } |
41 | 61 | ||
42 | static struct sa1100fb_mach_info h3100_lcd_info = { | 62 | static struct sa1100fb_mach_info h3100_lcd_info = { |
@@ -69,6 +89,11 @@ static void __init h3100_map_io(void) | |||
69 | /* | 89 | /* |
70 | * This turns the IRDA power on or off on the Compaq H3100 | 90 | * This turns the IRDA power on or off on the Compaq H3100 |
71 | */ | 91 | */ |
92 | static struct gpio h3100_irda_gpio[] = { | ||
93 | { H3100_GPIO_IR_ON, GPIOF_OUT_INIT_LOW, "IrDA power" }, | ||
94 | { H3100_GPIO_IR_FSEL, GPIOF_OUT_INIT_LOW, "IrDA fsel" }, | ||
95 | }; | ||
96 | |||
72 | static int h3100_irda_set_power(struct device *dev, unsigned int state) | 97 | static int h3100_irda_set_power(struct device *dev, unsigned int state) |
73 | { | 98 | { |
74 | gpio_set_value(H3100_GPIO_IR_ON, state); | 99 | gpio_set_value(H3100_GPIO_IR_ON, state); |
@@ -80,18 +105,27 @@ static void h3100_irda_set_speed(struct device *dev, unsigned int speed) | |||
80 | gpio_set_value(H3100_GPIO_IR_FSEL, !(speed < 4000000)); | 105 | gpio_set_value(H3100_GPIO_IR_FSEL, !(speed < 4000000)); |
81 | } | 106 | } |
82 | 107 | ||
108 | static int h3100_irda_startup(struct device *dev) | ||
109 | { | ||
110 | return gpio_request_array(h3100_irda_gpio, sizeof(h3100_irda_gpio)); | ||
111 | } | ||
112 | |||
113 | static void h3100_irda_shutdown(struct device *dev) | ||
114 | { | ||
115 | return gpio_free_array(h3100_irda_gpio, sizeof(h3100_irda_gpio)); | ||
116 | } | ||
117 | |||
83 | static struct irda_platform_data h3100_irda_data = { | 118 | static struct irda_platform_data h3100_irda_data = { |
84 | .set_power = h3100_irda_set_power, | 119 | .set_power = h3100_irda_set_power, |
85 | .set_speed = h3100_irda_set_speed, | 120 | .set_speed = h3100_irda_set_speed, |
121 | .startup = h3100_irda_startup, | ||
122 | .shutdown = h3100_irda_shutdown, | ||
86 | }; | 123 | }; |
87 | 124 | ||
88 | static struct gpio_default_state h3100_default_gpio[] = { | 125 | static struct gpio_default_state h3100_default_gpio[] = { |
89 | { H3100_GPIO_IR_ON, GPIO_MODE_OUT0, "IrDA power" }, | ||
90 | { H3100_GPIO_IR_FSEL, GPIO_MODE_OUT0, "IrDA fsel" }, | ||
91 | { H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" }, | 126 | { H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" }, |
92 | { H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" }, | 127 | { H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" }, |
93 | { H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" }, | 128 | { H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" }, |
94 | { H3100_GPIO_LCD_3V_ON, GPIO_MODE_OUT0, "LCD 3v" }, | ||
95 | }; | 129 | }; |
96 | 130 | ||
97 | static void __init h3100_mach_init(void) | 131 | static void __init h3100_mach_init(void) |
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index b8dc5bd22623..a663e7230141 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c | |||
@@ -28,35 +28,39 @@ | |||
28 | /* | 28 | /* |
29 | * helper for sa1100fb | 29 | * helper for sa1100fb |
30 | */ | 30 | */ |
31 | static struct gpio h3600_lcd_gpio[] = { | ||
32 | { H3XXX_EGPIO_LCD_ON, GPIOF_OUT_INIT_LOW, "LCD power" }, | ||
33 | { H3600_EGPIO_LCD_PCI, GPIOF_OUT_INIT_LOW, "LCD control" }, | ||
34 | { H3600_EGPIO_LCD_5V_ON, GPIOF_OUT_INIT_LOW, "LCD 5v" }, | ||
35 | { H3600_EGPIO_LVDD_ON, GPIOF_OUT_INIT_LOW, "LCD 9v/-6.5v" }, | ||
36 | }; | ||
37 | |||
38 | static bool h3600_lcd_request(void) | ||
39 | { | ||
40 | static bool h3600_lcd_ok; | ||
41 | int rc; | ||
42 | |||
43 | if (h3600_lcd_ok) | ||
44 | return true; | ||
45 | |||
46 | rc = gpio_request_array(h3600_lcd_gpio, ARRAY_SIZE(h3600_lcd_gpio)); | ||
47 | if (rc) | ||
48 | pr_err("%s: can't request GPIOs\n", __func__); | ||
49 | else | ||
50 | h3600_lcd_ok = true; | ||
51 | |||
52 | return h3600_lcd_ok; | ||
53 | } | ||
54 | |||
31 | static void h3600_lcd_power(int enable) | 55 | static void h3600_lcd_power(int enable) |
32 | { | 56 | { |
33 | if (gpio_request(H3XXX_EGPIO_LCD_ON, "LCD power")) { | 57 | if (!h3600_lcd_request()) |
34 | pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__); | 58 | return; |
35 | goto err1; | ||
36 | } | ||
37 | if (gpio_request(H3600_EGPIO_LCD_PCI, "LCD control")) { | ||
38 | pr_err("%s: can't request H3XXX_EGPIO_LCD_PCI\n", __func__); | ||
39 | goto err2; | ||
40 | } | ||
41 | if (gpio_request(H3600_EGPIO_LCD_5V_ON, "LCD 5v")) { | ||
42 | pr_err("%s: can't request H3XXX_EGPIO_LCD_5V_ON\n", __func__); | ||
43 | goto err3; | ||
44 | } | ||
45 | if (gpio_request(H3600_EGPIO_LVDD_ON, "LCD 9v/-6.5v")) { | ||
46 | pr_err("%s: can't request H3600_EGPIO_LVDD_ON\n", __func__); | ||
47 | goto err4; | ||
48 | } | ||
49 | 59 | ||
50 | gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable); | 60 | gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable); |
51 | gpio_direction_output(H3600_EGPIO_LCD_PCI, enable); | 61 | gpio_direction_output(H3600_EGPIO_LCD_PCI, enable); |
52 | gpio_direction_output(H3600_EGPIO_LCD_5V_ON, enable); | 62 | gpio_direction_output(H3600_EGPIO_LCD_5V_ON, enable); |
53 | gpio_direction_output(H3600_EGPIO_LVDD_ON, enable); | 63 | gpio_direction_output(H3600_EGPIO_LVDD_ON, enable); |
54 | |||
55 | gpio_free(H3600_EGPIO_LVDD_ON); | ||
56 | err4: gpio_free(H3600_EGPIO_LCD_5V_ON); | ||
57 | err3: gpio_free(H3600_EGPIO_LCD_PCI); | ||
58 | err2: gpio_free(H3XXX_EGPIO_LCD_ON); | ||
59 | err1: return; | ||
60 | } | 64 | } |
61 | 65 | ||
62 | static const struct sa1100fb_rgb h3600_rgb_16 = { | 66 | static const struct sa1100fb_rgb h3600_rgb_16 = { |
@@ -93,6 +97,11 @@ static void __init h3600_map_io(void) | |||
93 | /* | 97 | /* |
94 | * This turns the IRDA power on or off on the Compaq H3600 | 98 | * This turns the IRDA power on or off on the Compaq H3600 |
95 | */ | 99 | */ |
100 | static struct gpio h3600_irda_gpio[] = { | ||
101 | { H3600_EGPIO_IR_ON, GPIOF_OUT_INIT_LOW, "IrDA power" }, | ||
102 | { H3600_EGPIO_IR_FSEL, GPIOF_OUT_INIT_LOW, "IrDA fsel" }, | ||
103 | }; | ||
104 | |||
96 | static int h3600_irda_set_power(struct device *dev, unsigned int state) | 105 | static int h3600_irda_set_power(struct device *dev, unsigned int state) |
97 | { | 106 | { |
98 | gpio_set_value(H3600_EGPIO_IR_ON, state); | 107 | gpio_set_value(H3600_EGPIO_IR_ON, state); |
@@ -106,29 +115,12 @@ static void h3600_irda_set_speed(struct device *dev, unsigned int speed) | |||
106 | 115 | ||
107 | static int h3600_irda_startup(struct device *dev) | 116 | static int h3600_irda_startup(struct device *dev) |
108 | { | 117 | { |
109 | int err = gpio_request(H3600_EGPIO_IR_ON, "IrDA power"); | 118 | return gpio_request_array(h3600_irda_gpio, sizeof(h3600_irda_gpio)); |
110 | if (err) | ||
111 | goto err1; | ||
112 | err = gpio_direction_output(H3600_EGPIO_IR_ON, 0); | ||
113 | if (err) | ||
114 | goto err2; | ||
115 | err = gpio_request(H3600_EGPIO_IR_FSEL, "IrDA fsel"); | ||
116 | if (err) | ||
117 | goto err2; | ||
118 | err = gpio_direction_output(H3600_EGPIO_IR_FSEL, 0); | ||
119 | if (err) | ||
120 | goto err3; | ||
121 | return 0; | ||
122 | |||
123 | err3: gpio_free(H3600_EGPIO_IR_FSEL); | ||
124 | err2: gpio_free(H3600_EGPIO_IR_ON); | ||
125 | err1: return err; | ||
126 | } | 119 | } |
127 | 120 | ||
128 | static void h3600_irda_shutdown(struct device *dev) | 121 | static void h3600_irda_shutdown(struct device *dev) |
129 | { | 122 | { |
130 | gpio_free(H3600_EGPIO_IR_ON); | 123 | return gpio_free_array(h3600_irda_gpio, sizeof(h3600_irda_gpio)); |
131 | gpio_free(H3600_EGPIO_IR_FSEL); | ||
132 | } | 124 | } |
133 | 125 | ||
134 | static struct irda_platform_data h3600_irda_data = { | 126 | static struct irda_platform_data h3600_irda_data = { |
diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h index 307391488c22..c23fcdb047a5 100644 --- a/arch/arm/mach-sa1100/include/mach/assabet.h +++ b/arch/arm/mach-sa1100/include/mach/assabet.h | |||
@@ -39,8 +39,8 @@ extern unsigned long SCR_value; | |||
39 | 39 | ||
40 | #define ASSABET_BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */ | 40 | #define ASSABET_BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */ |
41 | #define ASSABET_BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */ | 41 | #define ASSABET_BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */ |
42 | #define ASSABET_BCR_GFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */ | 42 | #define ASSABET_BCR_NGFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */ |
43 | #define ASSABET_BCR_CODEC_RST (1<<2) /* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */ | 43 | #define ASSABET_BCR_NCODEC_RST (1<<2) /* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */ |
44 | #define ASSABET_BCR_IRDA_FSEL (1<<3) /* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */ | 44 | #define ASSABET_BCR_IRDA_FSEL (1<<3) /* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */ |
45 | #define ASSABET_BCR_IRDA_MD0 (1<<4) /* Range/Power select */ | 45 | #define ASSABET_BCR_IRDA_MD0 (1<<4) /* Range/Power select */ |
46 | #define ASSABET_BCR_IRDA_MD1 (1<<5) /* Range/Power select */ | 46 | #define ASSABET_BCR_IRDA_MD1 (1<<5) /* Range/Power select */ |
@@ -69,6 +69,8 @@ extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set); | |||
69 | #define ASSABET_BCR_frob(x,y) do { } while (0) | 69 | #define ASSABET_BCR_frob(x,y) do { } while (0) |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | extern void assabet_uda1341_reset(int set); | ||
73 | |||
72 | #define ASSABET_BCR_set(x) ASSABET_BCR_frob((x), (x)) | 74 | #define ASSABET_BCR_set(x) ASSABET_BCR_frob((x), (x)) |
73 | #define ASSABET_BCR_clear(x) ASSABET_BCR_frob((x), 0) | 75 | #define ASSABET_BCR_clear(x) ASSABET_BCR_frob((x), 0) |
74 | 76 | ||
diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h index bdb356498a74..b1dd8584bed4 100644 --- a/arch/arm/mach-ux500/setup.h +++ b/arch/arm/mach-ux500/setup.h | |||
@@ -43,7 +43,7 @@ extern void ux500_timer_init(void); | |||
43 | .virtual = IO_ADDRESS(x), \ | 43 | .virtual = IO_ADDRESS(x), \ |
44 | .pfn = __phys_to_pfn(x), \ | 44 | .pfn = __phys_to_pfn(x), \ |
45 | .length = sz, \ | 45 | .length = sz, \ |
46 | .type = MT_MEMORY, \ | 46 | .type = MT_MEMORY_RWX, \ |
47 | } | 47 | } |
48 | 48 | ||
49 | extern struct smp_operations ux500_smp_ops; | 49 | extern struct smp_operations ux500_smp_ops; |
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index ecfe6e53f6e0..7f39ce2f841f 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
@@ -12,6 +12,7 @@ ifneq ($(CONFIG_MMU),y) | |||
12 | obj-y += nommu.o | 12 | obj-y += nommu.o |
13 | endif | 13 | endif |
14 | 14 | ||
15 | obj-$(CONFIG_ARM_PTDUMP) += dump.o | ||
15 | obj-$(CONFIG_MODULES) += proc-syms.o | 16 | obj-$(CONFIG_MODULES) += proc-syms.o |
16 | 17 | ||
17 | obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o | 18 | obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 447da6ffadd5..7abde2ce8973 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
27 | #include <asm/hardware/cache-l2x0.h> | 27 | #include <asm/hardware/cache-l2x0.h> |
28 | #include "cache-tauros3.h" | ||
28 | #include "cache-aurora-l2.h" | 29 | #include "cache-aurora-l2.h" |
29 | 30 | ||
30 | #define CACHE_LINE_SIZE 32 | 31 | #define CACHE_LINE_SIZE 32 |
@@ -767,6 +768,14 @@ static void aurora_save(void) | |||
767 | l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); | 768 | l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); |
768 | } | 769 | } |
769 | 770 | ||
771 | static void __init tauros3_save(void) | ||
772 | { | ||
773 | l2x0_saved_regs.aux2_ctrl = | ||
774 | readl_relaxed(l2x0_base + TAUROS3_AUX2_CTRL); | ||
775 | l2x0_saved_regs.prefetch_ctrl = | ||
776 | readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL); | ||
777 | } | ||
778 | |||
770 | static void l2x0_resume(void) | 779 | static void l2x0_resume(void) |
771 | { | 780 | { |
772 | if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { | 781 | if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { |
@@ -821,6 +830,18 @@ static void aurora_resume(void) | |||
821 | } | 830 | } |
822 | } | 831 | } |
823 | 832 | ||
833 | static void tauros3_resume(void) | ||
834 | { | ||
835 | if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { | ||
836 | writel_relaxed(l2x0_saved_regs.aux2_ctrl, | ||
837 | l2x0_base + TAUROS3_AUX2_CTRL); | ||
838 | writel_relaxed(l2x0_saved_regs.prefetch_ctrl, | ||
839 | l2x0_base + L2X0_PREFETCH_CTRL); | ||
840 | } | ||
841 | |||
842 | l2x0_resume(); | ||
843 | } | ||
844 | |||
824 | static void __init aurora_broadcast_l2_commands(void) | 845 | static void __init aurora_broadcast_l2_commands(void) |
825 | { | 846 | { |
826 | __u32 u; | 847 | __u32 u; |
@@ -906,6 +927,15 @@ static const struct l2x0_of_data aurora_no_outer_data = { | |||
906 | }, | 927 | }, |
907 | }; | 928 | }; |
908 | 929 | ||
930 | static const struct l2x0_of_data tauros3_data = { | ||
931 | .setup = NULL, | ||
932 | .save = tauros3_save, | ||
933 | /* Tauros3 broadcasts L1 cache operations to L2 */ | ||
934 | .outer_cache = { | ||
935 | .resume = tauros3_resume, | ||
936 | }, | ||
937 | }; | ||
938 | |||
909 | static const struct l2x0_of_data bcm_l2x0_data = { | 939 | static const struct l2x0_of_data bcm_l2x0_data = { |
910 | .setup = pl310_of_setup, | 940 | .setup = pl310_of_setup, |
911 | .save = pl310_save, | 941 | .save = pl310_save, |
@@ -922,17 +952,19 @@ static const struct l2x0_of_data bcm_l2x0_data = { | |||
922 | }; | 952 | }; |
923 | 953 | ||
924 | static const struct of_device_id l2x0_ids[] __initconst = { | 954 | static const struct of_device_id l2x0_ids[] __initconst = { |
925 | { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data }, | ||
926 | { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data }, | ||
927 | { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data }, | 955 | { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data }, |
928 | { .compatible = "marvell,aurora-system-cache", | 956 | { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data }, |
929 | .data = (void *)&aurora_no_outer_data}, | 957 | { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data }, |
930 | { .compatible = "marvell,aurora-outer-cache", | ||
931 | .data = (void *)&aurora_with_outer_data}, | ||
932 | { .compatible = "brcm,bcm11351-a2-pl310-cache", | ||
933 | .data = (void *)&bcm_l2x0_data}, | ||
934 | { .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */ | 958 | { .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */ |
935 | .data = (void *)&bcm_l2x0_data}, | 959 | .data = (void *)&bcm_l2x0_data}, |
960 | { .compatible = "brcm,bcm11351-a2-pl310-cache", | ||
961 | .data = (void *)&bcm_l2x0_data}, | ||
962 | { .compatible = "marvell,aurora-outer-cache", | ||
963 | .data = (void *)&aurora_with_outer_data}, | ||
964 | { .compatible = "marvell,aurora-system-cache", | ||
965 | .data = (void *)&aurora_no_outer_data}, | ||
966 | { .compatible = "marvell,tauros3-cache", | ||
967 | .data = (void *)&tauros3_data }, | ||
936 | {} | 968 | {} |
937 | }; | 969 | }; |
938 | 970 | ||
diff --git a/arch/arm/mm/cache-tauros3.h b/arch/arm/mm/cache-tauros3.h new file mode 100644 index 000000000000..02c0a97cbc02 --- /dev/null +++ b/arch/arm/mm/cache-tauros3.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Marvell Tauros3 cache controller includes | ||
3 | * | ||
4 | * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * | ||
6 | * based on GPL'ed 2.6 kernel sources | ||
7 | * (c) Marvell International Ltd. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef __ASM_ARM_HARDWARE_TAUROS3_H | ||
24 | #define __ASM_ARM_HARDWARE_TAUROS3_H | ||
25 | |||
26 | /* | ||
27 | * Marvell Tauros3 L2CC is compatible with PL310 r0p0 | ||
28 | * but with PREFETCH_CTRL (r2p0) and an additional event counter. | ||
29 | * Also, there is AUX2_CTRL for some Marvell specific control. | ||
30 | */ | ||
31 | |||
32 | #define TAUROS3_EVENT_CNT2_CFG 0x224 | ||
33 | #define TAUROS3_EVENT_CNT2_VAL 0x228 | ||
34 | #define TAUROS3_INV_ALL 0x780 | ||
35 | #define TAUROS3_CLEAN_ALL 0x784 | ||
36 | #define TAUROS3_AUX2_CTRL 0x820 | ||
37 | |||
38 | /* Registers shifts and masks */ | ||
39 | #define TAUROS3_AUX2_CTRL_LINEFILL_BURST8_EN (1 << 2) | ||
40 | |||
41 | #endif | ||
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index b5c467a65c27..778bcf88ee79 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -146,18 +146,18 @@ flush_levels: | |||
146 | ldr r7, =0x7fff | 146 | ldr r7, =0x7fff |
147 | ands r7, r7, r1, lsr #13 @ extract max number of the index size | 147 | ands r7, r7, r1, lsr #13 @ extract max number of the index size |
148 | loop1: | 148 | loop1: |
149 | mov r9, r4 @ create working copy of max way size | 149 | mov r9, r7 @ create working copy of max index |
150 | loop2: | 150 | loop2: |
151 | ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11 | 151 | ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11 |
152 | THUMB( lsl r6, r9, r5 ) | 152 | THUMB( lsl r6, r4, r5 ) |
153 | THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 | 153 | THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 |
154 | ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11 | 154 | ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11 |
155 | THUMB( lsl r6, r7, r2 ) | 155 | THUMB( lsl r6, r9, r2 ) |
156 | THUMB( orr r11, r11, r6 ) @ factor index number into r11 | 156 | THUMB( orr r11, r11, r6 ) @ factor index number into r11 |
157 | mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way | 157 | mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way |
158 | subs r9, r9, #1 @ decrement the way | 158 | subs r9, r9, #1 @ decrement the index |
159 | bge loop2 | 159 | bge loop2 |
160 | subs r7, r7, #1 @ decrement the index | 160 | subs r4, r4, #1 @ decrement the way |
161 | bge loop1 | 161 | bge loop1 |
162 | skip: | 162 | skip: |
163 | add r10, r10, #2 @ increment cache number | 163 | add r10, r10, #2 @ increment cache number |
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 84e6f772e204..6eb97b3a7481 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c | |||
@@ -36,8 +36,8 @@ | |||
36 | * The context ID is used by debuggers and trace logic, and | 36 | * The context ID is used by debuggers and trace logic, and |
37 | * should be unique within all running processes. | 37 | * should be unique within all running processes. |
38 | * | 38 | * |
39 | * In big endian operation, the two 32 bit words are swapped if accesed by | 39 | * In big endian operation, the two 32 bit words are swapped if accessed |
40 | * non 64-bit operations. | 40 | * by non-64-bit operations. |
41 | */ | 41 | */ |
42 | #define ASID_FIRST_VERSION (1ULL << ASID_BITS) | 42 | #define ASID_FIRST_VERSION (1ULL << ASID_BITS) |
43 | #define NUM_USER_ASIDS ASID_FIRST_VERSION | 43 | #define NUM_USER_ASIDS ASID_FIRST_VERSION |
@@ -78,20 +78,21 @@ void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm, | |||
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | #ifdef CONFIG_ARM_LPAE | 80 | #ifdef CONFIG_ARM_LPAE |
81 | static void cpu_set_reserved_ttbr0(void) | 81 | /* |
82 | { | 82 | * With LPAE, the ASID and page tables are updated atomicly, so there is |
83 | /* | 83 | * no need for a reserved set of tables (the active ASID tracking prevents |
84 | * Set TTBR0 to swapper_pg_dir which contains only global entries. The | 84 | * any issues across a rollover). |
85 | * ASID is set to 0. | 85 | */ |
86 | */ | 86 | #define cpu_set_reserved_ttbr0() |
87 | cpu_set_ttbr(0, __pa(swapper_pg_dir)); | ||
88 | isb(); | ||
89 | } | ||
90 | #else | 87 | #else |
91 | static void cpu_set_reserved_ttbr0(void) | 88 | static void cpu_set_reserved_ttbr0(void) |
92 | { | 89 | { |
93 | u32 ttb; | 90 | u32 ttb; |
94 | /* Copy TTBR1 into TTBR0 */ | 91 | /* |
92 | * Copy TTBR1 into TTBR0. | ||
93 | * This points at swapper_pg_dir, which contains only global | ||
94 | * entries so any speculative walks are perfectly safe. | ||
95 | */ | ||
95 | asm volatile( | 96 | asm volatile( |
96 | " mrc p15, 0, %0, c2, c0, 1 @ read TTBR1\n" | 97 | " mrc p15, 0, %0, c2, c0, 1 @ read TTBR1\n" |
97 | " mcr p15, 0, %0, c2, c0, 0 @ set TTBR0\n" | 98 | " mcr p15, 0, %0, c2, c0, 0 @ set TTBR0\n" |
@@ -179,6 +180,7 @@ static int is_reserved_asid(u64 asid) | |||
179 | 180 | ||
180 | static u64 new_context(struct mm_struct *mm, unsigned int cpu) | 181 | static u64 new_context(struct mm_struct *mm, unsigned int cpu) |
181 | { | 182 | { |
183 | static u32 cur_idx = 1; | ||
182 | u64 asid = atomic64_read(&mm->context.id); | 184 | u64 asid = atomic64_read(&mm->context.id); |
183 | u64 generation = atomic64_read(&asid_generation); | 185 | u64 generation = atomic64_read(&asid_generation); |
184 | 186 | ||
@@ -193,10 +195,13 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) | |||
193 | * Allocate a free ASID. If we can't find one, take a | 195 | * Allocate a free ASID. If we can't find one, take a |
194 | * note of the currently active ASIDs and mark the TLBs | 196 | * note of the currently active ASIDs and mark the TLBs |
195 | * as requiring flushes. We always count from ASID #1, | 197 | * as requiring flushes. We always count from ASID #1, |
196 | * as we reserve ASID #0 to switch via TTBR0 and indicate | 198 | * as we reserve ASID #0 to switch via TTBR0 and to |
197 | * rollover events. | 199 | * avoid speculative page table walks from hitting in |
200 | * any partial walk caches, which could be populated | ||
201 | * from overlapping level-1 descriptors used to map both | ||
202 | * the module area and the userspace stack. | ||
198 | */ | 203 | */ |
199 | asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); | 204 | asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx); |
200 | if (asid == NUM_USER_ASIDS) { | 205 | if (asid == NUM_USER_ASIDS) { |
201 | generation = atomic64_add_return(ASID_FIRST_VERSION, | 206 | generation = atomic64_add_return(ASID_FIRST_VERSION, |
202 | &asid_generation); | 207 | &asid_generation); |
@@ -204,6 +209,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) | |||
204 | asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); | 209 | asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); |
205 | } | 210 | } |
206 | __set_bit(asid, asid_map); | 211 | __set_bit(asid, asid_map); |
212 | cur_idx = asid; | ||
207 | asid |= generation; | 213 | asid |= generation; |
208 | cpumask_clear(mm_cpumask(mm)); | 214 | cpumask_clear(mm_cpumask(mm)); |
209 | } | 215 | } |
@@ -221,8 +227,9 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) | |||
221 | __check_vmalloc_seq(mm); | 227 | __check_vmalloc_seq(mm); |
222 | 228 | ||
223 | /* | 229 | /* |
224 | * Required during context switch to avoid speculative page table | 230 | * We cannot update the pgd and the ASID atomicly with classic |
225 | * walking with the wrong TTBR. | 231 | * MMU, so switch exclusively to global mappings to avoid |
232 | * speculative page table walking with the wrong TTBR. | ||
226 | */ | 233 | */ |
227 | cpu_set_reserved_ttbr0(); | 234 | cpu_set_reserved_ttbr0(); |
228 | 235 | ||
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f61a5707823a..1a77450e728a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -376,7 +376,7 @@ void __init init_dma_coherent_pool_size(unsigned long size) | |||
376 | static int __init atomic_pool_init(void) | 376 | static int __init atomic_pool_init(void) |
377 | { | 377 | { |
378 | struct dma_pool *pool = &atomic_pool; | 378 | struct dma_pool *pool = &atomic_pool; |
379 | pgprot_t prot = pgprot_dmacoherent(pgprot_kernel); | 379 | pgprot_t prot = pgprot_dmacoherent(PAGE_KERNEL); |
380 | gfp_t gfp = GFP_KERNEL | GFP_DMA; | 380 | gfp_t gfp = GFP_KERNEL | GFP_DMA; |
381 | unsigned long nr_pages = pool->size >> PAGE_SHIFT; | 381 | unsigned long nr_pages = pool->size >> PAGE_SHIFT; |
382 | unsigned long *bitmap; | 382 | unsigned long *bitmap; |
@@ -624,7 +624,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page, | |||
624 | if (PageHighMem(page)) | 624 | if (PageHighMem(page)) |
625 | __dma_free_remap(cpu_addr, size); | 625 | __dma_free_remap(cpu_addr, size); |
626 | else | 626 | else |
627 | __dma_remap(page, size, pgprot_kernel); | 627 | __dma_remap(page, size, PAGE_KERNEL); |
628 | dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT); | 628 | dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT); |
629 | } | 629 | } |
630 | 630 | ||
@@ -1351,7 +1351,7 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr, | |||
1351 | static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, | 1351 | static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, |
1352 | dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) | 1352 | dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) |
1353 | { | 1353 | { |
1354 | pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel); | 1354 | pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL); |
1355 | struct page **pages; | 1355 | struct page **pages; |
1356 | void *addr = NULL; | 1356 | void *addr = NULL; |
1357 | 1357 | ||
diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c new file mode 100644 index 000000000000..2b3a56414271 --- /dev/null +++ b/arch/arm/mm/dump.c | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * Debug helper to dump the current kernel pagetables of the system | ||
3 | * so that we can see what the various memory ranges are set to. | ||
4 | * | ||
5 | * Derived from x86 implementation: | ||
6 | * (C) Copyright 2008 Intel Corporation | ||
7 | * | ||
8 | * Author: Arjan van de Ven <arjan@linux.intel.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; version 2 | ||
13 | * of the License. | ||
14 | */ | ||
15 | #include <linux/debugfs.h> | ||
16 | #include <linux/fs.h> | ||
17 | #include <linux/mm.h> | ||
18 | #include <linux/seq_file.h> | ||
19 | |||
20 | #include <asm/fixmap.h> | ||
21 | #include <asm/pgtable.h> | ||
22 | |||
23 | struct addr_marker { | ||
24 | unsigned long start_address; | ||
25 | const char *name; | ||
26 | }; | ||
27 | |||
28 | static struct addr_marker address_markers[] = { | ||
29 | { MODULES_VADDR, "Modules" }, | ||
30 | { PAGE_OFFSET, "Kernel Mapping" }, | ||
31 | { 0, "vmalloc() Area" }, | ||
32 | { VMALLOC_END, "vmalloc() End" }, | ||
33 | { FIXADDR_START, "Fixmap Area" }, | ||
34 | { CONFIG_VECTORS_BASE, "Vectors" }, | ||
35 | { CONFIG_VECTORS_BASE + PAGE_SIZE * 2, "Vectors End" }, | ||
36 | { -1, NULL }, | ||
37 | }; | ||
38 | |||
39 | struct pg_state { | ||
40 | struct seq_file *seq; | ||
41 | const struct addr_marker *marker; | ||
42 | unsigned long start_address; | ||
43 | unsigned level; | ||
44 | u64 current_prot; | ||
45 | }; | ||
46 | |||
47 | struct prot_bits { | ||
48 | u64 mask; | ||
49 | u64 val; | ||
50 | const char *set; | ||
51 | const char *clear; | ||
52 | }; | ||
53 | |||
54 | static const struct prot_bits pte_bits[] = { | ||
55 | { | ||
56 | .mask = L_PTE_USER, | ||
57 | .val = L_PTE_USER, | ||
58 | .set = "USR", | ||
59 | .clear = " ", | ||
60 | }, { | ||
61 | .mask = L_PTE_RDONLY, | ||
62 | .val = L_PTE_RDONLY, | ||
63 | .set = "ro", | ||
64 | .clear = "RW", | ||
65 | }, { | ||
66 | .mask = L_PTE_XN, | ||
67 | .val = L_PTE_XN, | ||
68 | .set = "NX", | ||
69 | .clear = "x ", | ||
70 | }, { | ||
71 | .mask = L_PTE_SHARED, | ||
72 | .val = L_PTE_SHARED, | ||
73 | .set = "SHD", | ||
74 | .clear = " ", | ||
75 | }, { | ||
76 | .mask = L_PTE_MT_MASK, | ||
77 | .val = L_PTE_MT_UNCACHED, | ||
78 | .set = "SO/UNCACHED", | ||
79 | }, { | ||
80 | .mask = L_PTE_MT_MASK, | ||
81 | .val = L_PTE_MT_BUFFERABLE, | ||
82 | .set = "MEM/BUFFERABLE/WC", | ||
83 | }, { | ||
84 | .mask = L_PTE_MT_MASK, | ||
85 | .val = L_PTE_MT_WRITETHROUGH, | ||
86 | .set = "MEM/CACHED/WT", | ||
87 | }, { | ||
88 | .mask = L_PTE_MT_MASK, | ||
89 | .val = L_PTE_MT_WRITEBACK, | ||
90 | .set = "MEM/CACHED/WBRA", | ||
91 | #ifndef CONFIG_ARM_LPAE | ||
92 | }, { | ||
93 | .mask = L_PTE_MT_MASK, | ||
94 | .val = L_PTE_MT_MINICACHE, | ||
95 | .set = "MEM/MINICACHE", | ||
96 | #endif | ||
97 | }, { | ||
98 | .mask = L_PTE_MT_MASK, | ||
99 | .val = L_PTE_MT_WRITEALLOC, | ||
100 | .set = "MEM/CACHED/WBWA", | ||
101 | }, { | ||
102 | .mask = L_PTE_MT_MASK, | ||
103 | .val = L_PTE_MT_DEV_SHARED, | ||
104 | .set = "DEV/SHARED", | ||
105 | #ifndef CONFIG_ARM_LPAE | ||
106 | }, { | ||
107 | .mask = L_PTE_MT_MASK, | ||
108 | .val = L_PTE_MT_DEV_NONSHARED, | ||
109 | .set = "DEV/NONSHARED", | ||
110 | #endif | ||
111 | }, { | ||
112 | .mask = L_PTE_MT_MASK, | ||
113 | .val = L_PTE_MT_DEV_WC, | ||
114 | .set = "DEV/WC", | ||
115 | }, { | ||
116 | .mask = L_PTE_MT_MASK, | ||
117 | .val = L_PTE_MT_DEV_CACHED, | ||
118 | .set = "DEV/CACHED", | ||
119 | }, | ||
120 | }; | ||
121 | |||
122 | static const struct prot_bits section_bits[] = { | ||
123 | #ifndef CONFIG_ARM_LPAE | ||
124 | /* These are approximate */ | ||
125 | { | ||
126 | .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, | ||
127 | .val = 0, | ||
128 | .set = " ro", | ||
129 | }, { | ||
130 | .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, | ||
131 | .val = PMD_SECT_AP_WRITE, | ||
132 | .set = " RW", | ||
133 | }, { | ||
134 | .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, | ||
135 | .val = PMD_SECT_AP_READ, | ||
136 | .set = "USR ro", | ||
137 | }, { | ||
138 | .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, | ||
139 | .val = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, | ||
140 | .set = "USR RW", | ||
141 | #else | ||
142 | { | ||
143 | .mask = PMD_SECT_USER, | ||
144 | .val = PMD_SECT_USER, | ||
145 | .set = "USR", | ||
146 | }, { | ||
147 | .mask = PMD_SECT_RDONLY, | ||
148 | .val = PMD_SECT_RDONLY, | ||
149 | .set = "ro", | ||
150 | .clear = "RW", | ||
151 | #endif | ||
152 | }, { | ||
153 | .mask = PMD_SECT_XN, | ||
154 | .val = PMD_SECT_XN, | ||
155 | .set = "NX", | ||
156 | .clear = "x ", | ||
157 | }, { | ||
158 | .mask = PMD_SECT_S, | ||
159 | .val = PMD_SECT_S, | ||
160 | .set = "SHD", | ||
161 | .clear = " ", | ||
162 | }, | ||
163 | }; | ||
164 | |||
165 | struct pg_level { | ||
166 | const struct prot_bits *bits; | ||
167 | size_t num; | ||
168 | u64 mask; | ||
169 | }; | ||
170 | |||
171 | static struct pg_level pg_level[] = { | ||
172 | { | ||
173 | }, { /* pgd */ | ||
174 | }, { /* pud */ | ||
175 | }, { /* pmd */ | ||
176 | .bits = section_bits, | ||
177 | .num = ARRAY_SIZE(section_bits), | ||
178 | }, { /* pte */ | ||
179 | .bits = pte_bits, | ||
180 | .num = ARRAY_SIZE(pte_bits), | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | static void dump_prot(struct pg_state *st, const struct prot_bits *bits, size_t num) | ||
185 | { | ||
186 | unsigned i; | ||
187 | |||
188 | for (i = 0; i < num; i++, bits++) { | ||
189 | const char *s; | ||
190 | |||
191 | if ((st->current_prot & bits->mask) == bits->val) | ||
192 | s = bits->set; | ||
193 | else | ||
194 | s = bits->clear; | ||
195 | |||
196 | if (s) | ||
197 | seq_printf(st->seq, " %s", s); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u64 val) | ||
202 | { | ||
203 | static const char units[] = "KMGTPE"; | ||
204 | u64 prot = val & pg_level[level].mask; | ||
205 | |||
206 | if (addr < USER_PGTABLES_CEILING) | ||
207 | return; | ||
208 | |||
209 | if (!st->level) { | ||
210 | st->level = level; | ||
211 | st->current_prot = prot; | ||
212 | seq_printf(st->seq, "---[ %s ]---\n", st->marker->name); | ||
213 | } else if (prot != st->current_prot || level != st->level || | ||
214 | addr >= st->marker[1].start_address) { | ||
215 | const char *unit = units; | ||
216 | unsigned long delta; | ||
217 | |||
218 | if (st->current_prot) { | ||
219 | seq_printf(st->seq, "0x%08lx-0x%08lx ", | ||
220 | st->start_address, addr); | ||
221 | |||
222 | delta = (addr - st->start_address) >> 10; | ||
223 | while (!(delta & 1023) && unit[1]) { | ||
224 | delta >>= 10; | ||
225 | unit++; | ||
226 | } | ||
227 | seq_printf(st->seq, "%9lu%c", delta, *unit); | ||
228 | if (pg_level[st->level].bits) | ||
229 | dump_prot(st, pg_level[st->level].bits, pg_level[st->level].num); | ||
230 | seq_printf(st->seq, "\n"); | ||
231 | } | ||
232 | |||
233 | if (addr >= st->marker[1].start_address) { | ||
234 | st->marker++; | ||
235 | seq_printf(st->seq, "---[ %s ]---\n", st->marker->name); | ||
236 | } | ||
237 | st->start_address = addr; | ||
238 | st->current_prot = prot; | ||
239 | st->level = level; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start) | ||
244 | { | ||
245 | pte_t *pte = pte_offset_kernel(pmd, 0); | ||
246 | unsigned long addr; | ||
247 | unsigned i; | ||
248 | |||
249 | for (i = 0; i < PTRS_PER_PTE; i++, pte++) { | ||
250 | addr = start + i * PAGE_SIZE; | ||
251 | note_page(st, addr, 4, pte_val(*pte)); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) | ||
256 | { | ||
257 | pmd_t *pmd = pmd_offset(pud, 0); | ||
258 | unsigned long addr; | ||
259 | unsigned i; | ||
260 | |||
261 | for (i = 0; i < PTRS_PER_PMD; i++, pmd++) { | ||
262 | addr = start + i * PMD_SIZE; | ||
263 | if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd)) | ||
264 | note_page(st, addr, 3, pmd_val(*pmd)); | ||
265 | else | ||
266 | walk_pte(st, pmd, addr); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) | ||
271 | { | ||
272 | pud_t *pud = pud_offset(pgd, 0); | ||
273 | unsigned long addr; | ||
274 | unsigned i; | ||
275 | |||
276 | for (i = 0; i < PTRS_PER_PUD; i++, pud++) { | ||
277 | addr = start + i * PUD_SIZE; | ||
278 | if (!pud_none(*pud)) { | ||
279 | walk_pmd(st, pud, addr); | ||
280 | } else { | ||
281 | note_page(st, addr, 2, pud_val(*pud)); | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | |||
286 | static void walk_pgd(struct seq_file *m) | ||
287 | { | ||
288 | pgd_t *pgd = swapper_pg_dir; | ||
289 | struct pg_state st; | ||
290 | unsigned long addr; | ||
291 | unsigned i, pgdoff = USER_PGTABLES_CEILING / PGDIR_SIZE; | ||
292 | |||
293 | memset(&st, 0, sizeof(st)); | ||
294 | st.seq = m; | ||
295 | st.marker = address_markers; | ||
296 | |||
297 | pgd += pgdoff; | ||
298 | |||
299 | for (i = pgdoff; i < PTRS_PER_PGD; i++, pgd++) { | ||
300 | addr = i * PGDIR_SIZE; | ||
301 | if (!pgd_none(*pgd)) { | ||
302 | walk_pud(&st, pgd, addr); | ||
303 | } else { | ||
304 | note_page(&st, addr, 1, pgd_val(*pgd)); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | note_page(&st, 0, 0, 0); | ||
309 | } | ||
310 | |||
311 | static int ptdump_show(struct seq_file *m, void *v) | ||
312 | { | ||
313 | walk_pgd(m); | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int ptdump_open(struct inode *inode, struct file *file) | ||
318 | { | ||
319 | return single_open(file, ptdump_show, NULL); | ||
320 | } | ||
321 | |||
322 | static const struct file_operations ptdump_fops = { | ||
323 | .open = ptdump_open, | ||
324 | .read = seq_read, | ||
325 | .llseek = seq_lseek, | ||
326 | .release = single_release, | ||
327 | }; | ||
328 | |||
329 | static int ptdump_init(void) | ||
330 | { | ||
331 | struct dentry *pe; | ||
332 | unsigned i, j; | ||
333 | |||
334 | for (i = 0; i < ARRAY_SIZE(pg_level); i++) | ||
335 | if (pg_level[i].bits) | ||
336 | for (j = 0; j < pg_level[i].num; j++) | ||
337 | pg_level[i].mask |= pg_level[i].bits[j].mask; | ||
338 | |||
339 | address_markers[2].start_address = VMALLOC_START; | ||
340 | |||
341 | pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, | ||
342 | &ptdump_fops); | ||
343 | return pe ? 0 : -ENOMEM; | ||
344 | } | ||
345 | __initcall(ptdump_init); | ||
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 11eb8add7820..f57fb338cc8a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -142,58 +142,6 @@ static void __init find_limits(unsigned long *min, unsigned long *max_low, | |||
142 | *max_high = bank_pfn_end(&mi->bank[mi->nr_banks - 1]); | 142 | *max_high = bank_pfn_end(&mi->bank[mi->nr_banks - 1]); |
143 | } | 143 | } |
144 | 144 | ||
145 | static void __init arm_bootmem_init(unsigned long start_pfn, | ||
146 | unsigned long end_pfn) | ||
147 | { | ||
148 | struct memblock_region *reg; | ||
149 | unsigned int boot_pages; | ||
150 | phys_addr_t bitmap; | ||
151 | pg_data_t *pgdat; | ||
152 | |||
153 | /* | ||
154 | * Allocate the bootmem bitmap page. This must be in a region | ||
155 | * of memory which has already been mapped. | ||
156 | */ | ||
157 | boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn); | ||
158 | bitmap = memblock_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES, | ||
159 | __pfn_to_phys(end_pfn)); | ||
160 | |||
161 | /* | ||
162 | * Initialise the bootmem allocator, handing the | ||
163 | * memory banks over to bootmem. | ||
164 | */ | ||
165 | node_set_online(0); | ||
166 | pgdat = NODE_DATA(0); | ||
167 | init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn); | ||
168 | |||
169 | /* Free the lowmem regions from memblock into bootmem. */ | ||
170 | for_each_memblock(memory, reg) { | ||
171 | unsigned long start = memblock_region_memory_base_pfn(reg); | ||
172 | unsigned long end = memblock_region_memory_end_pfn(reg); | ||
173 | |||
174 | if (end >= end_pfn) | ||
175 | end = end_pfn; | ||
176 | if (start >= end) | ||
177 | break; | ||
178 | |||
179 | free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT); | ||
180 | } | ||
181 | |||
182 | /* Reserve the lowmem memblock reserved regions in bootmem. */ | ||
183 | for_each_memblock(reserved, reg) { | ||
184 | unsigned long start = memblock_region_reserved_base_pfn(reg); | ||
185 | unsigned long end = memblock_region_reserved_end_pfn(reg); | ||
186 | |||
187 | if (end >= end_pfn) | ||
188 | end = end_pfn; | ||
189 | if (start >= end) | ||
190 | break; | ||
191 | |||
192 | reserve_bootmem(__pfn_to_phys(start), | ||
193 | (end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | #ifdef CONFIG_ZONE_DMA | 145 | #ifdef CONFIG_ZONE_DMA |
198 | 146 | ||
199 | phys_addr_t arm_dma_zone_size __read_mostly; | 147 | phys_addr_t arm_dma_zone_size __read_mostly; |
@@ -233,7 +181,7 @@ void __init setup_dma_zone(const struct machine_desc *mdesc) | |||
233 | #endif | 181 | #endif |
234 | } | 182 | } |
235 | 183 | ||
236 | static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, | 184 | static void __init zone_sizes_init(unsigned long min, unsigned long max_low, |
237 | unsigned long max_high) | 185 | unsigned long max_high) |
238 | { | 186 | { |
239 | unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; | 187 | unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; |
@@ -381,7 +329,6 @@ void __init arm_memblock_init(struct meminfo *mi, | |||
381 | dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit)); | 329 | dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit)); |
382 | 330 | ||
383 | arm_memblock_steal_permitted = false; | 331 | arm_memblock_steal_permitted = false; |
384 | memblock_allow_resize(); | ||
385 | memblock_dump_all(); | 332 | memblock_dump_all(); |
386 | } | 333 | } |
387 | 334 | ||
@@ -389,12 +336,11 @@ void __init bootmem_init(void) | |||
389 | { | 336 | { |
390 | unsigned long min, max_low, max_high; | 337 | unsigned long min, max_low, max_high; |
391 | 338 | ||
339 | memblock_allow_resize(); | ||
392 | max_low = max_high = 0; | 340 | max_low = max_high = 0; |
393 | 341 | ||
394 | find_limits(&min, &max_low, &max_high); | 342 | find_limits(&min, &max_low, &max_high); |
395 | 343 | ||
396 | arm_bootmem_init(min, max_low); | ||
397 | |||
398 | /* | 344 | /* |
399 | * Sparsemem tries to allocate bootmem in memory_present(), | 345 | * Sparsemem tries to allocate bootmem in memory_present(), |
400 | * so must be done after the fixed reservations | 346 | * so must be done after the fixed reservations |
@@ -411,7 +357,7 @@ void __init bootmem_init(void) | |||
411 | * the sparse mem_map arrays initialized by sparse_init() | 357 | * the sparse mem_map arrays initialized by sparse_init() |
412 | * for memmap_init_zone(), otherwise all PFNs are invalid. | 358 | * for memmap_init_zone(), otherwise all PFNs are invalid. |
413 | */ | 359 | */ |
414 | arm_bootmem_free(min, max_low, max_high); | 360 | zone_sizes_init(min, max_low, max_high); |
415 | 361 | ||
416 | /* | 362 | /* |
417 | * This doesn't seem to be used by the Linux memory manager any | 363 | * This doesn't seem to be used by the Linux memory manager any |
@@ -584,7 +530,7 @@ void __init mem_init(void) | |||
584 | extern u32 itcm_end; | 530 | extern u32 itcm_end; |
585 | #endif | 531 | #endif |
586 | 532 | ||
587 | max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; | 533 | set_max_mapnr(pfn_to_page(max_pfn) - mem_map); |
588 | 534 | ||
589 | /* this will put all unused low memory onto the freelists */ | 535 | /* this will put all unused low memory onto the freelists */ |
590 | free_unused_memmap(&meminfo); | 536 | free_unused_memmap(&meminfo); |
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index f123d6eb074b..f9c32ba73544 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c | |||
@@ -392,9 +392,9 @@ __arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached) | |||
392 | unsigned int mtype; | 392 | unsigned int mtype; |
393 | 393 | ||
394 | if (cached) | 394 | if (cached) |
395 | mtype = MT_MEMORY; | 395 | mtype = MT_MEMORY_RWX; |
396 | else | 396 | else |
397 | mtype = MT_MEMORY_NONCACHED; | 397 | mtype = MT_MEMORY_RWX_NONCACHED; |
398 | 398 | ||
399 | return __arm_ioremap_caller(phys_addr, size, mtype, | 399 | return __arm_ioremap_caller(phys_addr, size, mtype, |
400 | __builtin_return_address(0)); | 400 | __builtin_return_address(0)); |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 580ef2de82d7..4f08c133cc25 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/cputype.h> | 22 | #include <asm/cputype.h> |
23 | #include <asm/sections.h> | 23 | #include <asm/sections.h> |
24 | #include <asm/cachetype.h> | 24 | #include <asm/cachetype.h> |
25 | #include <asm/sections.h> | ||
25 | #include <asm/setup.h> | 26 | #include <asm/setup.h> |
26 | #include <asm/smp_plat.h> | 27 | #include <asm/smp_plat.h> |
27 | #include <asm/tlb.h> | 28 | #include <asm/tlb.h> |
@@ -287,36 +288,43 @@ static struct mem_type mem_types[] = { | |||
287 | .prot_l1 = PMD_TYPE_TABLE, | 288 | .prot_l1 = PMD_TYPE_TABLE, |
288 | .domain = DOMAIN_USER, | 289 | .domain = DOMAIN_USER, |
289 | }, | 290 | }, |
290 | [MT_MEMORY] = { | 291 | [MT_MEMORY_RWX] = { |
291 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY, | 292 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY, |
292 | .prot_l1 = PMD_TYPE_TABLE, | 293 | .prot_l1 = PMD_TYPE_TABLE, |
293 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 294 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
294 | .domain = DOMAIN_KERNEL, | 295 | .domain = DOMAIN_KERNEL, |
295 | }, | 296 | }, |
297 | [MT_MEMORY_RW] = { | ||
298 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
299 | L_PTE_XN, | ||
300 | .prot_l1 = PMD_TYPE_TABLE, | ||
301 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | ||
302 | .domain = DOMAIN_KERNEL, | ||
303 | }, | ||
296 | [MT_ROM] = { | 304 | [MT_ROM] = { |
297 | .prot_sect = PMD_TYPE_SECT, | 305 | .prot_sect = PMD_TYPE_SECT, |
298 | .domain = DOMAIN_KERNEL, | 306 | .domain = DOMAIN_KERNEL, |
299 | }, | 307 | }, |
300 | [MT_MEMORY_NONCACHED] = { | 308 | [MT_MEMORY_RWX_NONCACHED] = { |
301 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | 309 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | |
302 | L_PTE_MT_BUFFERABLE, | 310 | L_PTE_MT_BUFFERABLE, |
303 | .prot_l1 = PMD_TYPE_TABLE, | 311 | .prot_l1 = PMD_TYPE_TABLE, |
304 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 312 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
305 | .domain = DOMAIN_KERNEL, | 313 | .domain = DOMAIN_KERNEL, |
306 | }, | 314 | }, |
307 | [MT_MEMORY_DTCM] = { | 315 | [MT_MEMORY_RW_DTCM] = { |
308 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | 316 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | |
309 | L_PTE_XN, | 317 | L_PTE_XN, |
310 | .prot_l1 = PMD_TYPE_TABLE, | 318 | .prot_l1 = PMD_TYPE_TABLE, |
311 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, | 319 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, |
312 | .domain = DOMAIN_KERNEL, | 320 | .domain = DOMAIN_KERNEL, |
313 | }, | 321 | }, |
314 | [MT_MEMORY_ITCM] = { | 322 | [MT_MEMORY_RWX_ITCM] = { |
315 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY, | 323 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY, |
316 | .prot_l1 = PMD_TYPE_TABLE, | 324 | .prot_l1 = PMD_TYPE_TABLE, |
317 | .domain = DOMAIN_KERNEL, | 325 | .domain = DOMAIN_KERNEL, |
318 | }, | 326 | }, |
319 | [MT_MEMORY_SO] = { | 327 | [MT_MEMORY_RW_SO] = { |
320 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | 328 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | |
321 | L_PTE_MT_UNCACHED | L_PTE_XN, | 329 | L_PTE_MT_UNCACHED | L_PTE_XN, |
322 | .prot_l1 = PMD_TYPE_TABLE, | 330 | .prot_l1 = PMD_TYPE_TABLE, |
@@ -325,7 +333,8 @@ static struct mem_type mem_types[] = { | |||
325 | .domain = DOMAIN_KERNEL, | 333 | .domain = DOMAIN_KERNEL, |
326 | }, | 334 | }, |
327 | [MT_MEMORY_DMA_READY] = { | 335 | [MT_MEMORY_DMA_READY] = { |
328 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY, | 336 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | |
337 | L_PTE_XN, | ||
329 | .prot_l1 = PMD_TYPE_TABLE, | 338 | .prot_l1 = PMD_TYPE_TABLE, |
330 | .domain = DOMAIN_KERNEL, | 339 | .domain = DOMAIN_KERNEL, |
331 | }, | 340 | }, |
@@ -337,6 +346,44 @@ const struct mem_type *get_mem_type(unsigned int type) | |||
337 | } | 346 | } |
338 | EXPORT_SYMBOL(get_mem_type); | 347 | EXPORT_SYMBOL(get_mem_type); |
339 | 348 | ||
349 | #define PTE_SET_FN(_name, pteop) \ | ||
350 | static int pte_set_##_name(pte_t *ptep, pgtable_t token, unsigned long addr, \ | ||
351 | void *data) \ | ||
352 | { \ | ||
353 | pte_t pte = pteop(*ptep); \ | ||
354 | \ | ||
355 | set_pte_ext(ptep, pte, 0); \ | ||
356 | return 0; \ | ||
357 | } \ | ||
358 | |||
359 | #define SET_MEMORY_FN(_name, callback) \ | ||
360 | int set_memory_##_name(unsigned long addr, int numpages) \ | ||
361 | { \ | ||
362 | unsigned long start = addr; \ | ||
363 | unsigned long size = PAGE_SIZE*numpages; \ | ||
364 | unsigned end = start + size; \ | ||
365 | \ | ||
366 | if (start < MODULES_VADDR || start >= MODULES_END) \ | ||
367 | return -EINVAL;\ | ||
368 | \ | ||
369 | if (end < MODULES_VADDR || end >= MODULES_END) \ | ||
370 | return -EINVAL; \ | ||
371 | \ | ||
372 | apply_to_page_range(&init_mm, start, size, callback, NULL); \ | ||
373 | flush_tlb_kernel_range(start, end); \ | ||
374 | return 0;\ | ||
375 | } | ||
376 | |||
377 | PTE_SET_FN(ro, pte_wrprotect) | ||
378 | PTE_SET_FN(rw, pte_mkwrite) | ||
379 | PTE_SET_FN(x, pte_mkexec) | ||
380 | PTE_SET_FN(nx, pte_mknexec) | ||
381 | |||
382 | SET_MEMORY_FN(ro, pte_set_ro) | ||
383 | SET_MEMORY_FN(rw, pte_set_rw) | ||
384 | SET_MEMORY_FN(x, pte_set_x) | ||
385 | SET_MEMORY_FN(nx, pte_set_nx) | ||
386 | |||
340 | /* | 387 | /* |
341 | * Adjust the PMD section entries according to the CPU in use. | 388 | * Adjust the PMD section entries according to the CPU in use. |
342 | */ | 389 | */ |
@@ -410,6 +457,9 @@ static void __init build_mem_type_table(void) | |||
410 | mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN; | 457 | mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN; |
411 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN; | 458 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN; |
412 | mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN; | 459 | mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN; |
460 | |||
461 | /* Also setup NX memory mapping */ | ||
462 | mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN; | ||
413 | } | 463 | } |
414 | if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { | 464 | if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { |
415 | /* | 465 | /* |
@@ -487,11 +537,13 @@ static void __init build_mem_type_table(void) | |||
487 | mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; | 537 | mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; |
488 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; | 538 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; |
489 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; | 539 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; |
490 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 540 | mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S; |
491 | mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; | 541 | mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED; |
542 | mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S; | ||
543 | mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED; | ||
492 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED; | 544 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED; |
493 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | 545 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S; |
494 | mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; | 546 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED; |
495 | } | 547 | } |
496 | } | 548 | } |
497 | 549 | ||
@@ -502,15 +554,15 @@ static void __init build_mem_type_table(void) | |||
502 | if (cpu_arch >= CPU_ARCH_ARMv6) { | 554 | if (cpu_arch >= CPU_ARCH_ARMv6) { |
503 | if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { | 555 | if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { |
504 | /* Non-cacheable Normal is XCB = 001 */ | 556 | /* Non-cacheable Normal is XCB = 001 */ |
505 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= | 557 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= |
506 | PMD_SECT_BUFFERED; | 558 | PMD_SECT_BUFFERED; |
507 | } else { | 559 | } else { |
508 | /* For both ARMv6 and non-TEX-remapping ARMv7 */ | 560 | /* For both ARMv6 and non-TEX-remapping ARMv7 */ |
509 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= | 561 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= |
510 | PMD_SECT_TEX(1); | 562 | PMD_SECT_TEX(1); |
511 | } | 563 | } |
512 | } else { | 564 | } else { |
513 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE; | 565 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE; |
514 | } | 566 | } |
515 | 567 | ||
516 | #ifdef CONFIG_ARM_LPAE | 568 | #ifdef CONFIG_ARM_LPAE |
@@ -543,10 +595,12 @@ static void __init build_mem_type_table(void) | |||
543 | 595 | ||
544 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; | 596 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; |
545 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; | 597 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; |
546 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; | 598 | mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd; |
547 | mem_types[MT_MEMORY].prot_pte |= kern_pgprot; | 599 | mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot; |
600 | mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd; | ||
601 | mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot; | ||
548 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot; | 602 | mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot; |
549 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask; | 603 | mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask; |
550 | mem_types[MT_ROM].prot_sect |= cp->pmd; | 604 | mem_types[MT_ROM].prot_sect |= cp->pmd; |
551 | 605 | ||
552 | switch (cp->pmd) { | 606 | switch (cp->pmd) { |
@@ -1296,6 +1350,8 @@ static void __init kmap_init(void) | |||
1296 | static void __init map_lowmem(void) | 1350 | static void __init map_lowmem(void) |
1297 | { | 1351 | { |
1298 | struct memblock_region *reg; | 1352 | struct memblock_region *reg; |
1353 | unsigned long kernel_x_start = round_down(__pa(_stext), SECTION_SIZE); | ||
1354 | unsigned long kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); | ||
1299 | 1355 | ||
1300 | /* Map all the lowmem memory banks. */ | 1356 | /* Map all the lowmem memory banks. */ |
1301 | for_each_memblock(memory, reg) { | 1357 | for_each_memblock(memory, reg) { |
@@ -1308,12 +1364,40 @@ static void __init map_lowmem(void) | |||
1308 | if (start >= end) | 1364 | if (start >= end) |
1309 | break; | 1365 | break; |
1310 | 1366 | ||
1311 | map.pfn = __phys_to_pfn(start); | 1367 | if (end < kernel_x_start || start >= kernel_x_end) { |
1312 | map.virtual = __phys_to_virt(start); | 1368 | map.pfn = __phys_to_pfn(start); |
1313 | map.length = end - start; | 1369 | map.virtual = __phys_to_virt(start); |
1314 | map.type = MT_MEMORY; | 1370 | map.length = end - start; |
1371 | map.type = MT_MEMORY_RWX; | ||
1315 | 1372 | ||
1316 | create_mapping(&map); | 1373 | create_mapping(&map); |
1374 | } else { | ||
1375 | /* This better cover the entire kernel */ | ||
1376 | if (start < kernel_x_start) { | ||
1377 | map.pfn = __phys_to_pfn(start); | ||
1378 | map.virtual = __phys_to_virt(start); | ||
1379 | map.length = kernel_x_start - start; | ||
1380 | map.type = MT_MEMORY_RW; | ||
1381 | |||
1382 | create_mapping(&map); | ||
1383 | } | ||
1384 | |||
1385 | map.pfn = __phys_to_pfn(kernel_x_start); | ||
1386 | map.virtual = __phys_to_virt(kernel_x_start); | ||
1387 | map.length = kernel_x_end - kernel_x_start; | ||
1388 | map.type = MT_MEMORY_RWX; | ||
1389 | |||
1390 | create_mapping(&map); | ||
1391 | |||
1392 | if (kernel_x_end < end) { | ||
1393 | map.pfn = __phys_to_pfn(kernel_x_end); | ||
1394 | map.virtual = __phys_to_virt(kernel_x_end); | ||
1395 | map.length = end - kernel_x_end; | ||
1396 | map.type = MT_MEMORY_RW; | ||
1397 | |||
1398 | create_mapping(&map); | ||
1399 | } | ||
1400 | } | ||
1317 | } | 1401 | } |
1318 | } | 1402 | } |
1319 | 1403 | ||
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 1046b373d1ae..249379535be2 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #define __pgd_alloc() kmalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL) | 23 | #define __pgd_alloc() kmalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL) |
24 | #define __pgd_free(pgd) kfree(pgd) | 24 | #define __pgd_free(pgd) kfree(pgd) |
25 | #else | 25 | #else |
26 | #define __pgd_alloc() (pgd_t *)__get_free_pages(GFP_KERNEL, 2) | 26 | #define __pgd_alloc() (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_REPEAT, 2) |
27 | #define __pgd_free(pgd) free_pages((unsigned long)pgd, 2) | 27 | #define __pgd_free(pgd) free_pages((unsigned long)pgd, 2) |
28 | #endif | 28 | #endif |
29 | 29 | ||
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index c4876ac9151a..9e6029105607 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -83,162 +83,6 @@ static struct device_attribute amba_dev_attrs[] = { | |||
83 | __ATTR_NULL, | 83 | __ATTR_NULL, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | #ifdef CONFIG_PM_SLEEP | ||
87 | |||
88 | static int amba_legacy_suspend(struct device *dev, pm_message_t mesg) | ||
89 | { | ||
90 | struct amba_driver *adrv = to_amba_driver(dev->driver); | ||
91 | struct amba_device *adev = to_amba_device(dev); | ||
92 | int ret = 0; | ||
93 | |||
94 | if (dev->driver && adrv->suspend) | ||
95 | ret = adrv->suspend(adev, mesg); | ||
96 | |||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | static int amba_legacy_resume(struct device *dev) | ||
101 | { | ||
102 | struct amba_driver *adrv = to_amba_driver(dev->driver); | ||
103 | struct amba_device *adev = to_amba_device(dev); | ||
104 | int ret = 0; | ||
105 | |||
106 | if (dev->driver && adrv->resume) | ||
107 | ret = adrv->resume(adev); | ||
108 | |||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | #endif /* CONFIG_PM_SLEEP */ | ||
113 | |||
114 | #ifdef CONFIG_SUSPEND | ||
115 | |||
116 | static int amba_pm_suspend(struct device *dev) | ||
117 | { | ||
118 | struct device_driver *drv = dev->driver; | ||
119 | int ret = 0; | ||
120 | |||
121 | if (!drv) | ||
122 | return 0; | ||
123 | |||
124 | if (drv->pm) { | ||
125 | if (drv->pm->suspend) | ||
126 | ret = drv->pm->suspend(dev); | ||
127 | } else { | ||
128 | ret = amba_legacy_suspend(dev, PMSG_SUSPEND); | ||
129 | } | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static int amba_pm_resume(struct device *dev) | ||
135 | { | ||
136 | struct device_driver *drv = dev->driver; | ||
137 | int ret = 0; | ||
138 | |||
139 | if (!drv) | ||
140 | return 0; | ||
141 | |||
142 | if (drv->pm) { | ||
143 | if (drv->pm->resume) | ||
144 | ret = drv->pm->resume(dev); | ||
145 | } else { | ||
146 | ret = amba_legacy_resume(dev); | ||
147 | } | ||
148 | |||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | #else /* !CONFIG_SUSPEND */ | ||
153 | |||
154 | #define amba_pm_suspend NULL | ||
155 | #define amba_pm_resume NULL | ||
156 | |||
157 | #endif /* !CONFIG_SUSPEND */ | ||
158 | |||
159 | #ifdef CONFIG_HIBERNATE_CALLBACKS | ||
160 | |||
161 | static int amba_pm_freeze(struct device *dev) | ||
162 | { | ||
163 | struct device_driver *drv = dev->driver; | ||
164 | int ret = 0; | ||
165 | |||
166 | if (!drv) | ||
167 | return 0; | ||
168 | |||
169 | if (drv->pm) { | ||
170 | if (drv->pm->freeze) | ||
171 | ret = drv->pm->freeze(dev); | ||
172 | } else { | ||
173 | ret = amba_legacy_suspend(dev, PMSG_FREEZE); | ||
174 | } | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int amba_pm_thaw(struct device *dev) | ||
180 | { | ||
181 | struct device_driver *drv = dev->driver; | ||
182 | int ret = 0; | ||
183 | |||
184 | if (!drv) | ||
185 | return 0; | ||
186 | |||
187 | if (drv->pm) { | ||
188 | if (drv->pm->thaw) | ||
189 | ret = drv->pm->thaw(dev); | ||
190 | } else { | ||
191 | ret = amba_legacy_resume(dev); | ||
192 | } | ||
193 | |||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static int amba_pm_poweroff(struct device *dev) | ||
198 | { | ||
199 | struct device_driver *drv = dev->driver; | ||
200 | int ret = 0; | ||
201 | |||
202 | if (!drv) | ||
203 | return 0; | ||
204 | |||
205 | if (drv->pm) { | ||
206 | if (drv->pm->poweroff) | ||
207 | ret = drv->pm->poweroff(dev); | ||
208 | } else { | ||
209 | ret = amba_legacy_suspend(dev, PMSG_HIBERNATE); | ||
210 | } | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | static int amba_pm_restore(struct device *dev) | ||
216 | { | ||
217 | struct device_driver *drv = dev->driver; | ||
218 | int ret = 0; | ||
219 | |||
220 | if (!drv) | ||
221 | return 0; | ||
222 | |||
223 | if (drv->pm) { | ||
224 | if (drv->pm->restore) | ||
225 | ret = drv->pm->restore(dev); | ||
226 | } else { | ||
227 | ret = amba_legacy_resume(dev); | ||
228 | } | ||
229 | |||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | #else /* !CONFIG_HIBERNATE_CALLBACKS */ | ||
234 | |||
235 | #define amba_pm_freeze NULL | ||
236 | #define amba_pm_thaw NULL | ||
237 | #define amba_pm_poweroff NULL | ||
238 | #define amba_pm_restore NULL | ||
239 | |||
240 | #endif /* !CONFIG_HIBERNATE_CALLBACKS */ | ||
241 | |||
242 | #ifdef CONFIG_PM_RUNTIME | 86 | #ifdef CONFIG_PM_RUNTIME |
243 | /* | 87 | /* |
244 | * Hooks to provide runtime PM of the pclk (bus clock). It is safe to | 88 | * Hooks to provide runtime PM of the pclk (bus clock). It is safe to |
@@ -251,7 +95,7 @@ static int amba_pm_runtime_suspend(struct device *dev) | |||
251 | int ret = pm_generic_runtime_suspend(dev); | 95 | int ret = pm_generic_runtime_suspend(dev); |
252 | 96 | ||
253 | if (ret == 0 && dev->driver) | 97 | if (ret == 0 && dev->driver) |
254 | clk_disable(pcdev->pclk); | 98 | clk_disable_unprepare(pcdev->pclk); |
255 | 99 | ||
256 | return ret; | 100 | return ret; |
257 | } | 101 | } |
@@ -262,7 +106,7 @@ static int amba_pm_runtime_resume(struct device *dev) | |||
262 | int ret; | 106 | int ret; |
263 | 107 | ||
264 | if (dev->driver) { | 108 | if (dev->driver) { |
265 | ret = clk_enable(pcdev->pclk); | 109 | ret = clk_prepare_enable(pcdev->pclk); |
266 | /* Failure is probably fatal to the system, but... */ | 110 | /* Failure is probably fatal to the system, but... */ |
267 | if (ret) | 111 | if (ret) |
268 | return ret; | 112 | return ret; |
@@ -272,15 +116,13 @@ static int amba_pm_runtime_resume(struct device *dev) | |||
272 | } | 116 | } |
273 | #endif | 117 | #endif |
274 | 118 | ||
275 | #ifdef CONFIG_PM | ||
276 | |||
277 | static const struct dev_pm_ops amba_pm = { | 119 | static const struct dev_pm_ops amba_pm = { |
278 | .suspend = amba_pm_suspend, | 120 | .suspend = pm_generic_suspend, |
279 | .resume = amba_pm_resume, | 121 | .resume = pm_generic_resume, |
280 | .freeze = amba_pm_freeze, | 122 | .freeze = pm_generic_freeze, |
281 | .thaw = amba_pm_thaw, | 123 | .thaw = pm_generic_thaw, |
282 | .poweroff = amba_pm_poweroff, | 124 | .poweroff = pm_generic_poweroff, |
283 | .restore = amba_pm_restore, | 125 | .restore = pm_generic_restore, |
284 | SET_RUNTIME_PM_OPS( | 126 | SET_RUNTIME_PM_OPS( |
285 | amba_pm_runtime_suspend, | 127 | amba_pm_runtime_suspend, |
286 | amba_pm_runtime_resume, | 128 | amba_pm_runtime_resume, |
@@ -288,14 +130,6 @@ static const struct dev_pm_ops amba_pm = { | |||
288 | ) | 130 | ) |
289 | }; | 131 | }; |
290 | 132 | ||
291 | #define AMBA_PM (&amba_pm) | ||
292 | |||
293 | #else /* !CONFIG_PM */ | ||
294 | |||
295 | #define AMBA_PM NULL | ||
296 | |||
297 | #endif /* !CONFIG_PM */ | ||
298 | |||
299 | /* | 133 | /* |
300 | * Primecells are part of the Advanced Microcontroller Bus Architecture, | 134 | * Primecells are part of the Advanced Microcontroller Bus Architecture, |
301 | * so we call the bus "amba". | 135 | * so we call the bus "amba". |
@@ -305,7 +139,7 @@ struct bus_type amba_bustype = { | |||
305 | .dev_attrs = amba_dev_attrs, | 139 | .dev_attrs = amba_dev_attrs, |
306 | .match = amba_match, | 140 | .match = amba_match, |
307 | .uevent = amba_uevent, | 141 | .uevent = amba_uevent, |
308 | .pm = AMBA_PM, | 142 | .pm = &amba_pm, |
309 | }; | 143 | }; |
310 | 144 | ||
311 | static int __init amba_init(void) | 145 | static int __init amba_init(void) |
@@ -317,36 +151,23 @@ postcore_initcall(amba_init); | |||
317 | 151 | ||
318 | static int amba_get_enable_pclk(struct amba_device *pcdev) | 152 | static int amba_get_enable_pclk(struct amba_device *pcdev) |
319 | { | 153 | { |
320 | struct clk *pclk = clk_get(&pcdev->dev, "apb_pclk"); | ||
321 | int ret; | 154 | int ret; |
322 | 155 | ||
323 | pcdev->pclk = pclk; | 156 | pcdev->pclk = clk_get(&pcdev->dev, "apb_pclk"); |
324 | 157 | if (IS_ERR(pcdev->pclk)) | |
325 | if (IS_ERR(pclk)) | 158 | return PTR_ERR(pcdev->pclk); |
326 | return PTR_ERR(pclk); | ||
327 | 159 | ||
328 | ret = clk_prepare(pclk); | 160 | ret = clk_prepare_enable(pcdev->pclk); |
329 | if (ret) { | 161 | if (ret) |
330 | clk_put(pclk); | 162 | clk_put(pcdev->pclk); |
331 | return ret; | ||
332 | } | ||
333 | |||
334 | ret = clk_enable(pclk); | ||
335 | if (ret) { | ||
336 | clk_unprepare(pclk); | ||
337 | clk_put(pclk); | ||
338 | } | ||
339 | 163 | ||
340 | return ret; | 164 | return ret; |
341 | } | 165 | } |
342 | 166 | ||
343 | static void amba_put_disable_pclk(struct amba_device *pcdev) | 167 | static void amba_put_disable_pclk(struct amba_device *pcdev) |
344 | { | 168 | { |
345 | struct clk *pclk = pcdev->pclk; | 169 | clk_disable_unprepare(pcdev->pclk); |
346 | 170 | clk_put(pcdev->pclk); | |
347 | clk_disable(pclk); | ||
348 | clk_unprepare(pclk); | ||
349 | clk_put(pclk); | ||
350 | } | 171 | } |
351 | 172 | ||
352 | /* | 173 | /* |
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 4e2fd44865e1..b7c206db0df8 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
@@ -167,8 +167,6 @@ static int amba_kmi_remove(struct amba_device *dev) | |||
167 | { | 167 | { |
168 | struct amba_kmi_port *kmi = amba_get_drvdata(dev); | 168 | struct amba_kmi_port *kmi = amba_get_drvdata(dev); |
169 | 169 | ||
170 | amba_set_drvdata(dev, NULL); | ||
171 | |||
172 | serio_unregister_port(kmi->io); | 170 | serio_unregister_port(kmi->io); |
173 | clk_put(kmi->clk); | 171 | clk_put(kmi->clk); |
174 | iounmap(kmi->base); | 172 | iounmap(kmi->base); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f32057972dd7..b93122636531 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -1683,8 +1683,6 @@ static int mmci_remove(struct amba_device *dev) | |||
1683 | { | 1683 | { |
1684 | struct mmc_host *mmc = amba_get_drvdata(dev); | 1684 | struct mmc_host *mmc = amba_get_drvdata(dev); |
1685 | 1685 | ||
1686 | amba_set_drvdata(dev, NULL); | ||
1687 | |||
1688 | if (mmc) { | 1686 | if (mmc) { |
1689 | struct mmci_host *host = mmc_priv(mmc); | 1687 | struct mmci_host *host = mmc_priv(mmc); |
1690 | 1688 | ||