diff options
Diffstat (limited to 'arch')
231 files changed, 9464 insertions, 5353 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0f3417065d13..fac58916adec 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -14,6 +14,7 @@ config ARM | |||
14 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) | 14 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) |
15 | select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) | 15 | select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) |
16 | select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) | 16 | select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) |
17 | select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) | ||
17 | select HAVE_GENERIC_DMA_COHERENT | 18 | select HAVE_GENERIC_DMA_COHERENT |
18 | select HAVE_KERNEL_GZIP | 19 | select HAVE_KERNEL_GZIP |
19 | select HAVE_KERNEL_LZO | 20 | select HAVE_KERNEL_LZO |
@@ -805,6 +806,7 @@ config ARCH_U8500 | |||
805 | select GENERIC_CLOCKEVENTS | 806 | select GENERIC_CLOCKEVENTS |
806 | select COMMON_CLKDEV | 807 | select COMMON_CLKDEV |
807 | select ARCH_REQUIRE_GPIOLIB | 808 | select ARCH_REQUIRE_GPIOLIB |
809 | select ARCH_HAS_CPUFREQ | ||
808 | help | 810 | help |
809 | Support for ST-Ericsson's Ux500 architecture | 811 | Support for ST-Ericsson's Ux500 architecture |
810 | 812 | ||
@@ -1009,8 +1011,8 @@ source arch/arm/mm/Kconfig | |||
1009 | 1011 | ||
1010 | config IWMMXT | 1012 | config IWMMXT |
1011 | bool "Enable iWMMXt support" | 1013 | bool "Enable iWMMXt support" |
1012 | depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK | 1014 | depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 |
1013 | default y if PXA27x || PXA3xx || ARCH_MMP | 1015 | default y if PXA27x || PXA3xx || PXA95x || ARCH_MMP |
1014 | help | 1016 | help |
1015 | Enable support for iWMMXt context switching at run time if | 1017 | Enable support for iWMMXt context switching at run time if |
1016 | running on a CPU that supports it. | 1018 | running on a CPU that supports it. |
@@ -1215,10 +1217,11 @@ config SMP | |||
1215 | depends on EXPERIMENTAL | 1217 | depends on EXPERIMENTAL |
1216 | depends on GENERIC_CLOCKEVENTS | 1218 | depends on GENERIC_CLOCKEVENTS |
1217 | depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ | 1219 | depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ |
1218 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ | 1220 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ |
1219 | ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 | 1221 | ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ |
1222 | ARCH_MSM_SCORPIONMP | ||
1220 | select USE_GENERIC_SMP_HELPERS | 1223 | select USE_GENERIC_SMP_HELPERS |
1221 | select HAVE_ARM_SCU | 1224 | select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP |
1222 | help | 1225 | help |
1223 | This enables support for systems with more than one CPU. If you have | 1226 | This enables support for systems with more than one CPU. If you have |
1224 | a system with only one CPU, like most personal computers, say N. If | 1227 | a system with only one CPU, like most personal computers, say N. If |
@@ -1293,6 +1296,7 @@ config NR_CPUS | |||
1293 | config HOTPLUG_CPU | 1296 | config HOTPLUG_CPU |
1294 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | 1297 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" |
1295 | depends on SMP && HOTPLUG && EXPERIMENTAL | 1298 | depends on SMP && HOTPLUG && EXPERIMENTAL |
1299 | depends on !ARCH_MSM | ||
1296 | help | 1300 | help |
1297 | Say Y here to experiment with turning CPUs off and on. CPUs | 1301 | Say Y here to experiment with turning CPUs off and on. CPUs |
1298 | can be controlled through /sys/devices/system/cpu. | 1302 | can be controlled through /sys/devices/system/cpu. |
@@ -1301,7 +1305,7 @@ config LOCAL_TIMERS | |||
1301 | bool "Use local timer interrupts" | 1305 | bool "Use local timer interrupts" |
1302 | depends on SMP | 1306 | depends on SMP |
1303 | default y | 1307 | default y |
1304 | select HAVE_ARM_TWD | 1308 | select HAVE_ARM_TWD if !ARCH_MSM_SCORPIONMP |
1305 | help | 1309 | help |
1306 | Enable support for local timers on SMP platforms, rather then the | 1310 | Enable support for local timers on SMP platforms, rather then the |
1307 | legacy IPI broadcast method. Local timers allows the system | 1311 | legacy IPI broadcast method. Local timers allows the system |
@@ -1321,7 +1325,7 @@ config HZ | |||
1321 | 1325 | ||
1322 | config THUMB2_KERNEL | 1326 | config THUMB2_KERNEL |
1323 | bool "Compile the kernel in Thumb-2 mode" | 1327 | bool "Compile the kernel in Thumb-2 mode" |
1324 | depends on CPU_V7 && EXPERIMENTAL | 1328 | depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL |
1325 | select AEABI | 1329 | select AEABI |
1326 | select ARM_ASM_UNIFIED | 1330 | select ARM_ASM_UNIFIED |
1327 | help | 1331 | help |
@@ -1769,7 +1773,7 @@ comment "At least one emulation must be selected" | |||
1769 | 1773 | ||
1770 | config FPE_NWFPE | 1774 | config FPE_NWFPE |
1771 | bool "NWFPE math emulation" | 1775 | bool "NWFPE math emulation" |
1772 | depends on !AEABI || OABI_COMPAT | 1776 | depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL |
1773 | ---help--- | 1777 | ---help--- |
1774 | Say Y to include the NWFPE floating point emulator in the kernel. | 1778 | Say Y to include the NWFPE floating point emulator in the kernel. |
1775 | This is necessary to run most binaries. Linux does not currently | 1779 | This is necessary to run most binaries. Linux does not currently |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 2fd0b99afc4b..eac62085f5b2 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -23,7 +23,7 @@ config STRICT_DEVMEM | |||
23 | config FRAME_POINTER | 23 | config FRAME_POINTER |
24 | bool | 24 | bool |
25 | depends on !THUMB2_KERNEL | 25 | depends on !THUMB2_KERNEL |
26 | default y if !ARM_UNWIND | 26 | default y if !ARM_UNWIND || FUNCTION_GRAPH_TRACER |
27 | help | 27 | help |
28 | If you say N here, the resulting kernel will be slightly smaller and | 28 | If you say N here, the resulting kernel will be slightly smaller and |
29 | faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled, | 29 | faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled, |
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index 4d8ae9d67abe..f389b2704d82 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h | |||
@@ -20,8 +20,8 @@ struct arch_hw_breakpoint_ctrl { | |||
20 | struct arch_hw_breakpoint { | 20 | struct arch_hw_breakpoint { |
21 | u32 address; | 21 | u32 address; |
22 | u32 trigger; | 22 | u32 trigger; |
23 | struct perf_event *suspended_wp; | 23 | struct arch_hw_breakpoint_ctrl step_ctrl; |
24 | struct arch_hw_breakpoint_ctrl ctrl; | 24 | struct arch_hw_breakpoint_ctrl ctrl; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) | 27 | static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) |
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 1120f18a6b17..ec4327a4653d 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
@@ -63,6 +63,11 @@ | |||
63 | #include <asm/outercache.h> | 63 | #include <asm/outercache.h> |
64 | 64 | ||
65 | #define __exception __attribute__((section(".exception.text"))) | 65 | #define __exception __attribute__((section(".exception.text"))) |
66 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
67 | #define __exception_irq_entry __irq_entry | ||
68 | #else | ||
69 | #define __exception_irq_entry __exception | ||
70 | #endif | ||
66 | 71 | ||
67 | struct thread_info; | 72 | struct thread_info; |
68 | struct task_struct; | 73 | struct task_struct; |
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index 491960bf4260..124475afb007 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h | |||
@@ -15,13 +15,32 @@ struct undef_hook { | |||
15 | void register_undef_hook(struct undef_hook *hook); | 15 | void register_undef_hook(struct undef_hook *hook); |
16 | void unregister_undef_hook(struct undef_hook *hook); | 16 | void unregister_undef_hook(struct undef_hook *hook); |
17 | 17 | ||
18 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
19 | static inline int __in_irqentry_text(unsigned long ptr) | ||
20 | { | ||
21 | extern char __irqentry_text_start[]; | ||
22 | extern char __irqentry_text_end[]; | ||
23 | |||
24 | return ptr >= (unsigned long)&__irqentry_text_start && | ||
25 | ptr < (unsigned long)&__irqentry_text_end; | ||
26 | } | ||
27 | #else | ||
28 | static inline int __in_irqentry_text(unsigned long ptr) | ||
29 | { | ||
30 | return 0; | ||
31 | } | ||
32 | #endif | ||
33 | |||
18 | static inline int in_exception_text(unsigned long ptr) | 34 | static inline int in_exception_text(unsigned long ptr) |
19 | { | 35 | { |
20 | extern char __exception_text_start[]; | 36 | extern char __exception_text_start[]; |
21 | extern char __exception_text_end[]; | 37 | extern char __exception_text_end[]; |
38 | int in; | ||
39 | |||
40 | in = ptr >= (unsigned long)&__exception_text_start && | ||
41 | ptr < (unsigned long)&__exception_text_end; | ||
22 | 42 | ||
23 | return ptr >= (unsigned long)&__exception_text_start && | 43 | return in ? : __in_irqentry_text(ptr); |
24 | ptr < (unsigned long)&__exception_text_end; | ||
25 | } | 44 | } |
26 | 45 | ||
27 | extern void __init early_trap_init(void); | 46 | extern void __init early_trap_init(void); |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5b9b268f4fbb..c73abe4b7e72 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) | 5 | CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) |
6 | AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) | 6 | AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) |
7 | 7 | ||
8 | ifdef CONFIG_DYNAMIC_FTRACE | 8 | ifdef CONFIG_FUNCTION_TRACER |
9 | CFLAGS_REMOVE_ftrace.o = -pg | 9 | CFLAGS_REMOVE_ftrace.o = -pg |
10 | endif | 10 | endif |
11 | 11 | ||
@@ -33,6 +33,7 @@ obj-$(CONFIG_SMP) += smp.o | |||
33 | obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o | 33 | obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o |
34 | obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o | 34 | obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o |
35 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 35 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
36 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | ||
36 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | 37 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o |
37 | obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o | 38 | obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o |
38 | obj-$(CONFIG_ATAGS_PROC) += atags.o | 39 | obj-$(CONFIG_ATAGS_PROC) += atags.o |
@@ -50,6 +51,7 @@ AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 | |||
50 | obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o | 51 | obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o |
51 | obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o | 52 | obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o |
52 | obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o | 53 | obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o |
54 | obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o | ||
53 | obj-$(CONFIG_IWMMXT) += iwmmxt.o | 55 | obj-$(CONFIG_IWMMXT) += iwmmxt.o |
54 | obj-$(CONFIG_CPU_HAS_PMU) += pmu.o | 56 | obj-$(CONFIG_CPU_HAS_PMU) += pmu.o |
55 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o | 57 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index bb96a7d4bbf5..36199ffc4cc2 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -198,6 +198,7 @@ __dabt_svc: | |||
198 | @ | 198 | @ |
199 | @ set desired IRQ state, then call main handler | 199 | @ set desired IRQ state, then call main handler |
200 | @ | 200 | @ |
201 | debug_entry r1 | ||
201 | msr cpsr_c, r9 | 202 | msr cpsr_c, r9 |
202 | mov r2, sp | 203 | mov r2, sp |
203 | bl do_DataAbort | 204 | bl do_DataAbort |
@@ -324,6 +325,7 @@ __pabt_svc: | |||
324 | #else | 325 | #else |
325 | bl CPU_PABORT_HANDLER | 326 | bl CPU_PABORT_HANDLER |
326 | #endif | 327 | #endif |
328 | debug_entry r1 | ||
327 | msr cpsr_c, r9 @ Maybe enable interrupts | 329 | msr cpsr_c, r9 @ Maybe enable interrupts |
328 | mov r2, sp @ regs | 330 | mov r2, sp @ regs |
329 | bl do_PrefetchAbort @ call abort handler | 331 | bl do_PrefetchAbort @ call abort handler |
@@ -439,6 +441,7 @@ __dabt_usr: | |||
439 | @ | 441 | @ |
440 | @ IRQs on, then call the main handler | 442 | @ IRQs on, then call the main handler |
441 | @ | 443 | @ |
444 | debug_entry r1 | ||
442 | enable_irq | 445 | enable_irq |
443 | mov r2, sp | 446 | mov r2, sp |
444 | adr lr, BSYM(ret_from_exception) | 447 | adr lr, BSYM(ret_from_exception) |
@@ -703,6 +706,7 @@ __pabt_usr: | |||
703 | #else | 706 | #else |
704 | bl CPU_PABORT_HANDLER | 707 | bl CPU_PABORT_HANDLER |
705 | #endif | 708 | #endif |
709 | debug_entry r1 | ||
706 | enable_irq @ Enable interrupts | 710 | enable_irq @ Enable interrupts |
707 | mov r2, sp @ regs | 711 | mov r2, sp @ regs |
708 | bl do_PrefetchAbort @ call abort handler | 712 | bl do_PrefetchAbort @ call abort handler |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 8bfa98757cd2..aae802ee12f8 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -141,98 +141,170 @@ ENDPROC(ret_from_fork) | |||
141 | #endif | 141 | #endif |
142 | #endif | 142 | #endif |
143 | 143 | ||
144 | #ifdef CONFIG_DYNAMIC_FTRACE | 144 | .macro __mcount suffix |
145 | ENTRY(__gnu_mcount_nc) | 145 | mcount_enter |
146 | mov ip, lr | 146 | ldr r0, =ftrace_trace_function |
147 | ldmia sp!, {lr} | 147 | ldr r2, [r0] |
148 | mov pc, ip | 148 | adr r0, .Lftrace_stub |
149 | ENDPROC(__gnu_mcount_nc) | 149 | cmp r0, r2 |
150 | bne 1f | ||
151 | |||
152 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
153 | ldr r1, =ftrace_graph_return | ||
154 | ldr r2, [r1] | ||
155 | cmp r0, r2 | ||
156 | bne ftrace_graph_caller\suffix | ||
157 | |||
158 | ldr r1, =ftrace_graph_entry | ||
159 | ldr r2, [r1] | ||
160 | ldr r0, =ftrace_graph_entry_stub | ||
161 | cmp r0, r2 | ||
162 | bne ftrace_graph_caller\suffix | ||
163 | #endif | ||
150 | 164 | ||
151 | ENTRY(ftrace_caller) | 165 | mcount_exit |
152 | stmdb sp!, {r0-r3, lr} | 166 | |
153 | mov r0, lr | 167 | 1: mcount_get_lr r1 @ lr of instrumented func |
168 | mov r0, lr @ instrumented function | ||
169 | sub r0, r0, #MCOUNT_INSN_SIZE | ||
170 | adr lr, BSYM(2f) | ||
171 | mov pc, r2 | ||
172 | 2: mcount_exit | ||
173 | .endm | ||
174 | |||
175 | .macro __ftrace_caller suffix | ||
176 | mcount_enter | ||
177 | |||
178 | mcount_get_lr r1 @ lr of instrumented func | ||
179 | mov r0, lr @ instrumented function | ||
154 | sub r0, r0, #MCOUNT_INSN_SIZE | 180 | sub r0, r0, #MCOUNT_INSN_SIZE |
155 | ldr r1, [sp, #20] | ||
156 | 181 | ||
157 | .global ftrace_call | 182 | .globl ftrace_call\suffix |
158 | ftrace_call: | 183 | ftrace_call\suffix: |
159 | bl ftrace_stub | 184 | bl ftrace_stub |
160 | ldmia sp!, {r0-r3, ip, lr} | 185 | |
161 | mov pc, ip | 186 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
162 | ENDPROC(ftrace_caller) | 187 | .globl ftrace_graph_call\suffix |
188 | ftrace_graph_call\suffix: | ||
189 | mov r0, r0 | ||
190 | #endif | ||
191 | |||
192 | mcount_exit | ||
193 | .endm | ||
194 | |||
195 | .macro __ftrace_graph_caller | ||
196 | sub r0, fp, #4 @ &lr of instrumented routine (&parent) | ||
197 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
198 | @ called from __ftrace_caller, saved in mcount_enter | ||
199 | ldr r1, [sp, #16] @ instrumented routine (func) | ||
200 | #else | ||
201 | @ called from __mcount, untouched in lr | ||
202 | mov r1, lr @ instrumented routine (func) | ||
203 | #endif | ||
204 | sub r1, r1, #MCOUNT_INSN_SIZE | ||
205 | mov r2, fp @ frame pointer | ||
206 | bl prepare_ftrace_return | ||
207 | mcount_exit | ||
208 | .endm | ||
163 | 209 | ||
164 | #ifdef CONFIG_OLD_MCOUNT | 210 | #ifdef CONFIG_OLD_MCOUNT |
211 | /* | ||
212 | * mcount | ||
213 | */ | ||
214 | |||
215 | .macro mcount_enter | ||
216 | stmdb sp!, {r0-r3, lr} | ||
217 | .endm | ||
218 | |||
219 | .macro mcount_get_lr reg | ||
220 | ldr \reg, [fp, #-4] | ||
221 | .endm | ||
222 | |||
223 | .macro mcount_exit | ||
224 | ldr lr, [fp, #-4] | ||
225 | ldmia sp!, {r0-r3, pc} | ||
226 | .endm | ||
227 | |||
165 | ENTRY(mcount) | 228 | ENTRY(mcount) |
229 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
166 | stmdb sp!, {lr} | 230 | stmdb sp!, {lr} |
167 | ldr lr, [fp, #-4] | 231 | ldr lr, [fp, #-4] |
168 | ldmia sp!, {pc} | 232 | ldmia sp!, {pc} |
233 | #else | ||
234 | __mcount _old | ||
235 | #endif | ||
169 | ENDPROC(mcount) | 236 | ENDPROC(mcount) |
170 | 237 | ||
238 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
171 | ENTRY(ftrace_caller_old) | 239 | ENTRY(ftrace_caller_old) |
172 | stmdb sp!, {r0-r3, lr} | 240 | __ftrace_caller _old |
173 | ldr r1, [fp, #-4] | ||
174 | mov r0, lr | ||
175 | sub r0, r0, #MCOUNT_INSN_SIZE | ||
176 | |||
177 | .globl ftrace_call_old | ||
178 | ftrace_call_old: | ||
179 | bl ftrace_stub | ||
180 | ldr lr, [fp, #-4] @ restore lr | ||
181 | ldmia sp!, {r0-r3, pc} | ||
182 | ENDPROC(ftrace_caller_old) | 241 | ENDPROC(ftrace_caller_old) |
183 | #endif | 242 | #endif |
184 | 243 | ||
185 | #else | 244 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
245 | ENTRY(ftrace_graph_caller_old) | ||
246 | __ftrace_graph_caller | ||
247 | ENDPROC(ftrace_graph_caller_old) | ||
248 | #endif | ||
186 | 249 | ||
187 | ENTRY(__gnu_mcount_nc) | 250 | .purgem mcount_enter |
251 | .purgem mcount_get_lr | ||
252 | .purgem mcount_exit | ||
253 | #endif | ||
254 | |||
255 | /* | ||
256 | * __gnu_mcount_nc | ||
257 | */ | ||
258 | |||
259 | .macro mcount_enter | ||
188 | stmdb sp!, {r0-r3, lr} | 260 | stmdb sp!, {r0-r3, lr} |
189 | ldr r0, =ftrace_trace_function | 261 | .endm |
190 | ldr r2, [r0] | 262 | |
191 | adr r0, .Lftrace_stub | 263 | .macro mcount_get_lr reg |
192 | cmp r0, r2 | 264 | ldr \reg, [sp, #20] |
193 | bne gnu_trace | 265 | .endm |
266 | |||
267 | .macro mcount_exit | ||
194 | ldmia sp!, {r0-r3, ip, lr} | 268 | ldmia sp!, {r0-r3, ip, lr} |
195 | mov pc, ip | 269 | mov pc, ip |
270 | .endm | ||
196 | 271 | ||
197 | gnu_trace: | 272 | ENTRY(__gnu_mcount_nc) |
198 | ldr r1, [sp, #20] @ lr of instrumented routine | 273 | #ifdef CONFIG_DYNAMIC_FTRACE |
199 | mov r0, lr | 274 | mov ip, lr |
200 | sub r0, r0, #MCOUNT_INSN_SIZE | 275 | ldmia sp!, {lr} |
201 | adr lr, BSYM(1f) | ||
202 | mov pc, r2 | ||
203 | 1: | ||
204 | ldmia sp!, {r0-r3, ip, lr} | ||
205 | mov pc, ip | 276 | mov pc, ip |
277 | #else | ||
278 | __mcount | ||
279 | #endif | ||
206 | ENDPROC(__gnu_mcount_nc) | 280 | ENDPROC(__gnu_mcount_nc) |
207 | 281 | ||
208 | #ifdef CONFIG_OLD_MCOUNT | 282 | #ifdef CONFIG_DYNAMIC_FTRACE |
209 | /* | 283 | ENTRY(ftrace_caller) |
210 | * This is under an ifdef in order to force link-time errors for people trying | 284 | __ftrace_caller |
211 | * to build with !FRAME_POINTER with a GCC which doesn't use the new-style | 285 | ENDPROC(ftrace_caller) |
212 | * mcount. | 286 | #endif |
213 | */ | ||
214 | ENTRY(mcount) | ||
215 | stmdb sp!, {r0-r3, lr} | ||
216 | ldr r0, =ftrace_trace_function | ||
217 | ldr r2, [r0] | ||
218 | adr r0, ftrace_stub | ||
219 | cmp r0, r2 | ||
220 | bne trace | ||
221 | ldr lr, [fp, #-4] @ restore lr | ||
222 | ldmia sp!, {r0-r3, pc} | ||
223 | 287 | ||
224 | trace: | 288 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
225 | ldr r1, [fp, #-4] @ lr of instrumented routine | 289 | ENTRY(ftrace_graph_caller) |
226 | mov r0, lr | 290 | __ftrace_graph_caller |
227 | sub r0, r0, #MCOUNT_INSN_SIZE | 291 | ENDPROC(ftrace_graph_caller) |
228 | mov lr, pc | ||
229 | mov pc, r2 | ||
230 | ldr lr, [fp, #-4] @ restore lr | ||
231 | ldmia sp!, {r0-r3, pc} | ||
232 | ENDPROC(mcount) | ||
233 | #endif | 292 | #endif |
234 | 293 | ||
235 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 294 | .purgem mcount_enter |
295 | .purgem mcount_get_lr | ||
296 | .purgem mcount_exit | ||
297 | |||
298 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
299 | .globl return_to_handler | ||
300 | return_to_handler: | ||
301 | stmdb sp!, {r0-r3} | ||
302 | mov r0, fp @ frame pointer | ||
303 | bl ftrace_return_to_handler | ||
304 | mov lr, r0 @ r0 has real ret addr | ||
305 | ldmia sp!, {r0-r3} | ||
306 | mov pc, lr | ||
307 | #endif | ||
236 | 308 | ||
237 | ENTRY(ftrace_stub) | 309 | ENTRY(ftrace_stub) |
238 | .Lftrace_stub: | 310 | .Lftrace_stub: |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index d93f976fb389..ae9464900168 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
@@ -165,6 +165,25 @@ | |||
165 | .endm | 165 | .endm |
166 | #endif /* !CONFIG_THUMB2_KERNEL */ | 166 | #endif /* !CONFIG_THUMB2_KERNEL */ |
167 | 167 | ||
168 | @ | ||
169 | @ Debug exceptions are taken as prefetch or data aborts. | ||
170 | @ We must disable preemption during the handler so that | ||
171 | @ we can access the debug registers safely. | ||
172 | @ | ||
173 | .macro debug_entry, fsr | ||
174 | #if defined(CONFIG_HAVE_HW_BREAKPOINT) && defined(CONFIG_PREEMPT) | ||
175 | ldr r4, =0x40f @ mask out fsr.fs | ||
176 | and r5, r4, \fsr | ||
177 | cmp r5, #2 @ debug exception | ||
178 | bne 1f | ||
179 | get_thread_info r10 | ||
180 | ldr r6, [r10, #TI_PREEMPT] @ get preempt count | ||
181 | add r11, r6, #1 @ increment it | ||
182 | str r11, [r10, #TI_PREEMPT] | ||
183 | 1: | ||
184 | #endif | ||
185 | .endm | ||
186 | |||
168 | /* | 187 | /* |
169 | * These are the registers used in the syscall handler, and allow us to | 188 | * These are the registers used in the syscall handler, and allow us to |
170 | * have in theory up to 7 arguments to a function - r0 to r6. | 189 | * have in theory up to 7 arguments to a function - r0 to r6. |
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 971ac8c36ea7..c0062ad1e847 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #define NOP 0xe8bd4000 /* pop {lr} */ | 24 | #define NOP 0xe8bd4000 /* pop {lr} */ |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
27 | #ifdef CONFIG_OLD_MCOUNT | 28 | #ifdef CONFIG_OLD_MCOUNT |
28 | #define OLD_MCOUNT_ADDR ((unsigned long) mcount) | 29 | #define OLD_MCOUNT_ADDR ((unsigned long) mcount) |
29 | #define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old) | 30 | #define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old) |
@@ -59,9 +60,9 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr) | |||
59 | } | 60 | } |
60 | #endif | 61 | #endif |
61 | 62 | ||
62 | /* construct a branch (BL) instruction to addr */ | ||
63 | #ifdef CONFIG_THUMB2_KERNEL | 63 | #ifdef CONFIG_THUMB2_KERNEL |
64 | static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | 64 | static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, |
65 | bool link) | ||
65 | { | 66 | { |
66 | unsigned long s, j1, j2, i1, i2, imm10, imm11; | 67 | unsigned long s, j1, j2, i1, i2, imm10, imm11; |
67 | unsigned long first, second; | 68 | unsigned long first, second; |
@@ -83,15 +84,22 @@ static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | |||
83 | j2 = (!i2) ^ s; | 84 | j2 = (!i2) ^ s; |
84 | 85 | ||
85 | first = 0xf000 | (s << 10) | imm10; | 86 | first = 0xf000 | (s << 10) | imm10; |
86 | second = 0xd000 | (j1 << 13) | (j2 << 11) | imm11; | 87 | second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11; |
88 | if (link) | ||
89 | second |= 1 << 14; | ||
87 | 90 | ||
88 | return (second << 16) | first; | 91 | return (second << 16) | first; |
89 | } | 92 | } |
90 | #else | 93 | #else |
91 | static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | 94 | static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, |
95 | bool link) | ||
92 | { | 96 | { |
97 | unsigned long opcode = 0xea000000; | ||
93 | long offset; | 98 | long offset; |
94 | 99 | ||
100 | if (link) | ||
101 | opcode |= 1 << 24; | ||
102 | |||
95 | offset = (long)addr - (long)(pc + 8); | 103 | offset = (long)addr - (long)(pc + 8); |
96 | if (unlikely(offset < -33554432 || offset > 33554428)) { | 104 | if (unlikely(offset < -33554432 || offset > 33554428)) { |
97 | /* Can't generate branches that far (from ARM ARM). Ftrace | 105 | /* Can't generate branches that far (from ARM ARM). Ftrace |
@@ -103,10 +111,15 @@ static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | |||
103 | 111 | ||
104 | offset = (offset >> 2) & 0x00ffffff; | 112 | offset = (offset >> 2) & 0x00ffffff; |
105 | 113 | ||
106 | return 0xeb000000 | offset; | 114 | return opcode | offset; |
107 | } | 115 | } |
108 | #endif | 116 | #endif |
109 | 117 | ||
118 | static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | ||
119 | { | ||
120 | return ftrace_gen_branch(pc, addr, true); | ||
121 | } | ||
122 | |||
110 | static int ftrace_modify_code(unsigned long pc, unsigned long old, | 123 | static int ftrace_modify_code(unsigned long pc, unsigned long old, |
111 | unsigned long new) | 124 | unsigned long new) |
112 | { | 125 | { |
@@ -193,3 +206,83 @@ int __init ftrace_dyn_arch_init(void *data) | |||
193 | 206 | ||
194 | return 0; | 207 | return 0; |
195 | } | 208 | } |
209 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
210 | |||
211 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
212 | void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | ||
213 | unsigned long frame_pointer) | ||
214 | { | ||
215 | unsigned long return_hooker = (unsigned long) &return_to_handler; | ||
216 | struct ftrace_graph_ent trace; | ||
217 | unsigned long old; | ||
218 | int err; | ||
219 | |||
220 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | ||
221 | return; | ||
222 | |||
223 | old = *parent; | ||
224 | *parent = return_hooker; | ||
225 | |||
226 | err = ftrace_push_return_trace(old, self_addr, &trace.depth, | ||
227 | frame_pointer); | ||
228 | if (err == -EBUSY) { | ||
229 | *parent = old; | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | trace.func = self_addr; | ||
234 | |||
235 | /* Only trace if the calling function expects to */ | ||
236 | if (!ftrace_graph_entry(&trace)) { | ||
237 | current->curr_ret_stack--; | ||
238 | *parent = old; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
243 | extern unsigned long ftrace_graph_call; | ||
244 | extern unsigned long ftrace_graph_call_old; | ||
245 | extern void ftrace_graph_caller_old(void); | ||
246 | |||
247 | static int __ftrace_modify_caller(unsigned long *callsite, | ||
248 | void (*func) (void), bool enable) | ||
249 | { | ||
250 | unsigned long caller_fn = (unsigned long) func; | ||
251 | unsigned long pc = (unsigned long) callsite; | ||
252 | unsigned long branch = ftrace_gen_branch(pc, caller_fn, false); | ||
253 | unsigned long nop = 0xe1a00000; /* mov r0, r0 */ | ||
254 | unsigned long old = enable ? nop : branch; | ||
255 | unsigned long new = enable ? branch : nop; | ||
256 | |||
257 | return ftrace_modify_code(pc, old, new); | ||
258 | } | ||
259 | |||
260 | static int ftrace_modify_graph_caller(bool enable) | ||
261 | { | ||
262 | int ret; | ||
263 | |||
264 | ret = __ftrace_modify_caller(&ftrace_graph_call, | ||
265 | ftrace_graph_caller, | ||
266 | enable); | ||
267 | |||
268 | #ifdef CONFIG_OLD_MCOUNT | ||
269 | if (!ret) | ||
270 | ret = __ftrace_modify_caller(&ftrace_graph_call_old, | ||
271 | ftrace_graph_caller_old, | ||
272 | enable); | ||
273 | #endif | ||
274 | |||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | int ftrace_enable_ftrace_graph_caller(void) | ||
279 | { | ||
280 | return ftrace_modify_graph_caller(true); | ||
281 | } | ||
282 | |||
283 | int ftrace_disable_ftrace_graph_caller(void) | ||
284 | { | ||
285 | return ftrace_modify_graph_caller(false); | ||
286 | } | ||
287 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
288 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 21e3a4ab3b8c..c9f3f0467570 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #define pr_fmt(fmt) "hw-breakpoint: " fmt | 24 | #define pr_fmt(fmt) "hw-breakpoint: " fmt |
25 | 25 | ||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/hardirq.h> | ||
27 | #include <linux/perf_event.h> | 28 | #include <linux/perf_event.h> |
28 | #include <linux/hw_breakpoint.h> | 29 | #include <linux/hw_breakpoint.h> |
29 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
@@ -44,6 +45,7 @@ static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]); | |||
44 | 45 | ||
45 | /* Number of BRP/WRP registers on this CPU. */ | 46 | /* Number of BRP/WRP registers on this CPU. */ |
46 | static int core_num_brps; | 47 | static int core_num_brps; |
48 | static int core_num_reserved_brps; | ||
47 | static int core_num_wrps; | 49 | static int core_num_wrps; |
48 | 50 | ||
49 | /* Debug architecture version. */ | 51 | /* Debug architecture version. */ |
@@ -52,87 +54,6 @@ static u8 debug_arch; | |||
52 | /* Maximum supported watchpoint length. */ | 54 | /* Maximum supported watchpoint length. */ |
53 | static u8 max_watchpoint_len; | 55 | static u8 max_watchpoint_len; |
54 | 56 | ||
55 | /* Determine number of BRP registers available. */ | ||
56 | static int get_num_brps(void) | ||
57 | { | ||
58 | u32 didr; | ||
59 | ARM_DBG_READ(c0, 0, didr); | ||
60 | return ((didr >> 24) & 0xf) + 1; | ||
61 | } | ||
62 | |||
63 | /* Determine number of WRP registers available. */ | ||
64 | static int get_num_wrps(void) | ||
65 | { | ||
66 | /* | ||
67 | * FIXME: When a watchpoint fires, the only way to work out which | ||
68 | * watchpoint it was is by disassembling the faulting instruction | ||
69 | * and working out the address of the memory access. | ||
70 | * | ||
71 | * Furthermore, we can only do this if the watchpoint was precise | ||
72 | * since imprecise watchpoints prevent us from calculating register | ||
73 | * based addresses. | ||
74 | * | ||
75 | * For the time being, we only report 1 watchpoint register so we | ||
76 | * always know which watchpoint fired. In the future we can either | ||
77 | * add a disassembler and address generation emulator, or we can | ||
78 | * insert a check to see if the DFAR is set on watchpoint exception | ||
79 | * entry [the ARM ARM states that the DFAR is UNKNOWN, but | ||
80 | * experience shows that it is set on some implementations]. | ||
81 | */ | ||
82 | |||
83 | #if 0 | ||
84 | u32 didr, wrps; | ||
85 | ARM_DBG_READ(c0, 0, didr); | ||
86 | return ((didr >> 28) & 0xf) + 1; | ||
87 | #endif | ||
88 | |||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | int hw_breakpoint_slots(int type) | ||
93 | { | ||
94 | /* | ||
95 | * We can be called early, so don't rely on | ||
96 | * our static variables being initialised. | ||
97 | */ | ||
98 | switch (type) { | ||
99 | case TYPE_INST: | ||
100 | return get_num_brps(); | ||
101 | case TYPE_DATA: | ||
102 | return get_num_wrps(); | ||
103 | default: | ||
104 | pr_warning("unknown slot type: %d\n", type); | ||
105 | return 0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* Determine debug architecture. */ | ||
110 | static u8 get_debug_arch(void) | ||
111 | { | ||
112 | u32 didr; | ||
113 | |||
114 | /* Do we implement the extended CPUID interface? */ | ||
115 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | ||
116 | pr_warning("CPUID feature registers not supported. " | ||
117 | "Assuming v6 debug is present.\n"); | ||
118 | return ARM_DEBUG_ARCH_V6; | ||
119 | } | ||
120 | |||
121 | ARM_DBG_READ(c0, 0, didr); | ||
122 | return (didr >> 16) & 0xf; | ||
123 | } | ||
124 | |||
125 | /* Does this core support mismatch breakpoints? */ | ||
126 | static int core_has_mismatch_bps(void) | ||
127 | { | ||
128 | return debug_arch >= ARM_DEBUG_ARCH_V7_ECP14 && core_num_brps > 1; | ||
129 | } | ||
130 | |||
131 | u8 arch_get_debug_arch(void) | ||
132 | { | ||
133 | return debug_arch; | ||
134 | } | ||
135 | |||
136 | #define READ_WB_REG_CASE(OP2, M, VAL) \ | 57 | #define READ_WB_REG_CASE(OP2, M, VAL) \ |
137 | case ((OP2 << 4) + M): \ | 58 | case ((OP2 << 4) + M): \ |
138 | ARM_DBG_READ(c ## M, OP2, VAL); \ | 59 | ARM_DBG_READ(c ## M, OP2, VAL); \ |
@@ -210,6 +131,94 @@ static void write_wb_reg(int n, u32 val) | |||
210 | isb(); | 131 | isb(); |
211 | } | 132 | } |
212 | 133 | ||
134 | /* Determine debug architecture. */ | ||
135 | static u8 get_debug_arch(void) | ||
136 | { | ||
137 | u32 didr; | ||
138 | |||
139 | /* Do we implement the extended CPUID interface? */ | ||
140 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | ||
141 | pr_warning("CPUID feature registers not supported. " | ||
142 | "Assuming v6 debug is present.\n"); | ||
143 | return ARM_DEBUG_ARCH_V6; | ||
144 | } | ||
145 | |||
146 | ARM_DBG_READ(c0, 0, didr); | ||
147 | return (didr >> 16) & 0xf; | ||
148 | } | ||
149 | |||
150 | u8 arch_get_debug_arch(void) | ||
151 | { | ||
152 | return debug_arch; | ||
153 | } | ||
154 | |||
155 | /* Determine number of BRP register available. */ | ||
156 | static int get_num_brp_resources(void) | ||
157 | { | ||
158 | u32 didr; | ||
159 | ARM_DBG_READ(c0, 0, didr); | ||
160 | return ((didr >> 24) & 0xf) + 1; | ||
161 | } | ||
162 | |||
163 | /* Does this core support mismatch breakpoints? */ | ||
164 | static int core_has_mismatch_brps(void) | ||
165 | { | ||
166 | return (get_debug_arch() >= ARM_DEBUG_ARCH_V7_ECP14 && | ||
167 | get_num_brp_resources() > 1); | ||
168 | } | ||
169 | |||
170 | /* Determine number of usable WRPs available. */ | ||
171 | static int get_num_wrps(void) | ||
172 | { | ||
173 | /* | ||
174 | * FIXME: When a watchpoint fires, the only way to work out which | ||
175 | * watchpoint it was is by disassembling the faulting instruction | ||
176 | * and working out the address of the memory access. | ||
177 | * | ||
178 | * Furthermore, we can only do this if the watchpoint was precise | ||
179 | * since imprecise watchpoints prevent us from calculating register | ||
180 | * based addresses. | ||
181 | * | ||
182 | * Providing we have more than 1 breakpoint register, we only report | ||
183 | * a single watchpoint register for the time being. This way, we always | ||
184 | * know which watchpoint fired. In the future we can either add a | ||
185 | * disassembler and address generation emulator, or we can insert a | ||
186 | * check to see if the DFAR is set on watchpoint exception entry | ||
187 | * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows | ||
188 | * that it is set on some implementations]. | ||
189 | */ | ||
190 | |||
191 | #if 0 | ||
192 | int wrps; | ||
193 | u32 didr; | ||
194 | ARM_DBG_READ(c0, 0, didr); | ||
195 | wrps = ((didr >> 28) & 0xf) + 1; | ||
196 | #endif | ||
197 | int wrps = 1; | ||
198 | |||
199 | if (core_has_mismatch_brps() && wrps >= get_num_brp_resources()) | ||
200 | wrps = get_num_brp_resources() - 1; | ||
201 | |||
202 | return wrps; | ||
203 | } | ||
204 | |||
205 | /* We reserve one breakpoint for each watchpoint. */ | ||
206 | static int get_num_reserved_brps(void) | ||
207 | { | ||
208 | if (core_has_mismatch_brps()) | ||
209 | return get_num_wrps(); | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /* Determine number of usable BRPs available. */ | ||
214 | static int get_num_brps(void) | ||
215 | { | ||
216 | int brps = get_num_brp_resources(); | ||
217 | if (core_has_mismatch_brps()) | ||
218 | brps -= get_num_reserved_brps(); | ||
219 | return brps; | ||
220 | } | ||
221 | |||
213 | /* | 222 | /* |
214 | * In order to access the breakpoint/watchpoint control registers, | 223 | * In order to access the breakpoint/watchpoint control registers, |
215 | * we must be running in debug monitor mode. Unfortunately, we can | 224 | * we must be running in debug monitor mode. Unfortunately, we can |
@@ -230,8 +239,12 @@ static int enable_monitor_mode(void) | |||
230 | goto out; | 239 | goto out; |
231 | } | 240 | } |
232 | 241 | ||
242 | /* If monitor mode is already enabled, just return. */ | ||
243 | if (dscr & ARM_DSCR_MDBGEN) | ||
244 | goto out; | ||
245 | |||
233 | /* Write to the corresponding DSCR. */ | 246 | /* Write to the corresponding DSCR. */ |
234 | switch (debug_arch) { | 247 | switch (get_debug_arch()) { |
235 | case ARM_DEBUG_ARCH_V6: | 248 | case ARM_DEBUG_ARCH_V6: |
236 | case ARM_DEBUG_ARCH_V6_1: | 249 | case ARM_DEBUG_ARCH_V6_1: |
237 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); | 250 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); |
@@ -246,15 +259,30 @@ static int enable_monitor_mode(void) | |||
246 | 259 | ||
247 | /* Check that the write made it through. */ | 260 | /* Check that the write made it through. */ |
248 | ARM_DBG_READ(c1, 0, dscr); | 261 | ARM_DBG_READ(c1, 0, dscr); |
249 | if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN), | 262 | if (!(dscr & ARM_DSCR_MDBGEN)) |
250 | "failed to enable monitor mode.")) { | ||
251 | ret = -EPERM; | 263 | ret = -EPERM; |
252 | } | ||
253 | 264 | ||
254 | out: | 265 | out: |
255 | return ret; | 266 | return ret; |
256 | } | 267 | } |
257 | 268 | ||
269 | int hw_breakpoint_slots(int type) | ||
270 | { | ||
271 | /* | ||
272 | * We can be called early, so don't rely on | ||
273 | * our static variables being initialised. | ||
274 | */ | ||
275 | switch (type) { | ||
276 | case TYPE_INST: | ||
277 | return get_num_brps(); | ||
278 | case TYPE_DATA: | ||
279 | return get_num_wrps(); | ||
280 | default: | ||
281 | pr_warning("unknown slot type: %d\n", type); | ||
282 | return 0; | ||
283 | } | ||
284 | } | ||
285 | |||
258 | /* | 286 | /* |
259 | * Check if 8-bit byte-address select is available. | 287 | * Check if 8-bit byte-address select is available. |
260 | * This clobbers WRP 0. | 288 | * This clobbers WRP 0. |
@@ -268,9 +296,6 @@ static u8 get_max_wp_len(void) | |||
268 | if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14) | 296 | if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14) |
269 | goto out; | 297 | goto out; |
270 | 298 | ||
271 | if (enable_monitor_mode()) | ||
272 | goto out; | ||
273 | |||
274 | memset(&ctrl, 0, sizeof(ctrl)); | 299 | memset(&ctrl, 0, sizeof(ctrl)); |
275 | ctrl.len = ARM_BREAKPOINT_LEN_8; | 300 | ctrl.len = ARM_BREAKPOINT_LEN_8; |
276 | ctrl_reg = encode_ctrl_reg(ctrl); | 301 | ctrl_reg = encode_ctrl_reg(ctrl); |
@@ -290,23 +315,6 @@ u8 arch_get_max_wp_len(void) | |||
290 | } | 315 | } |
291 | 316 | ||
292 | /* | 317 | /* |
293 | * Handler for reactivating a suspended watchpoint when the single | ||
294 | * step `mismatch' breakpoint is triggered. | ||
295 | */ | ||
296 | static void wp_single_step_handler(struct perf_event *bp, int unused, | ||
297 | struct perf_sample_data *data, | ||
298 | struct pt_regs *regs) | ||
299 | { | ||
300 | perf_event_enable(counter_arch_bp(bp)->suspended_wp); | ||
301 | unregister_hw_breakpoint(bp); | ||
302 | } | ||
303 | |||
304 | static int bp_is_single_step(struct perf_event *bp) | ||
305 | { | ||
306 | return bp->overflow_handler == wp_single_step_handler; | ||
307 | } | ||
308 | |||
309 | /* | ||
310 | * Install a perf counter breakpoint. | 318 | * Install a perf counter breakpoint. |
311 | */ | 319 | */ |
312 | int arch_install_hw_breakpoint(struct perf_event *bp) | 320 | int arch_install_hw_breakpoint(struct perf_event *bp) |
@@ -314,30 +322,41 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
314 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 322 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
315 | struct perf_event **slot, **slots; | 323 | struct perf_event **slot, **slots; |
316 | int i, max_slots, ctrl_base, val_base, ret = 0; | 324 | int i, max_slots, ctrl_base, val_base, ret = 0; |
325 | u32 addr, ctrl; | ||
317 | 326 | ||
318 | /* Ensure that we are in monitor mode and halting mode is disabled. */ | 327 | /* Ensure that we are in monitor mode and halting mode is disabled. */ |
319 | ret = enable_monitor_mode(); | 328 | ret = enable_monitor_mode(); |
320 | if (ret) | 329 | if (ret) |
321 | goto out; | 330 | goto out; |
322 | 331 | ||
332 | addr = info->address; | ||
333 | ctrl = encode_ctrl_reg(info->ctrl) | 0x1; | ||
334 | |||
323 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { | 335 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { |
324 | /* Breakpoint */ | 336 | /* Breakpoint */ |
325 | ctrl_base = ARM_BASE_BCR; | 337 | ctrl_base = ARM_BASE_BCR; |
326 | val_base = ARM_BASE_BVR; | 338 | val_base = ARM_BASE_BVR; |
327 | slots = __get_cpu_var(bp_on_reg); | 339 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); |
328 | max_slots = core_num_brps - 1; | 340 | max_slots = core_num_brps; |
329 | 341 | if (info->step_ctrl.enabled) { | |
330 | if (bp_is_single_step(bp)) { | 342 | /* Override the breakpoint data with the step data. */ |
331 | info->ctrl.mismatch = 1; | 343 | addr = info->trigger & ~0x3; |
332 | i = max_slots; | 344 | ctrl = encode_ctrl_reg(info->step_ctrl); |
333 | slots[i] = bp; | ||
334 | goto setup; | ||
335 | } | 345 | } |
336 | } else { | 346 | } else { |
337 | /* Watchpoint */ | 347 | /* Watchpoint */ |
338 | ctrl_base = ARM_BASE_WCR; | 348 | if (info->step_ctrl.enabled) { |
339 | val_base = ARM_BASE_WVR; | 349 | /* Install into the reserved breakpoint region. */ |
340 | slots = __get_cpu_var(wp_on_reg); | 350 | ctrl_base = ARM_BASE_BCR + core_num_brps; |
351 | val_base = ARM_BASE_BVR + core_num_brps; | ||
352 | /* Override the watchpoint data with the step data. */ | ||
353 | addr = info->trigger & ~0x3; | ||
354 | ctrl = encode_ctrl_reg(info->step_ctrl); | ||
355 | } else { | ||
356 | ctrl_base = ARM_BASE_WCR; | ||
357 | val_base = ARM_BASE_WVR; | ||
358 | } | ||
359 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
341 | max_slots = core_num_wrps; | 360 | max_slots = core_num_wrps; |
342 | } | 361 | } |
343 | 362 | ||
@@ -355,12 +374,11 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
355 | goto out; | 374 | goto out; |
356 | } | 375 | } |
357 | 376 | ||
358 | setup: | ||
359 | /* Setup the address register. */ | 377 | /* Setup the address register. */ |
360 | write_wb_reg(val_base + i, info->address); | 378 | write_wb_reg(val_base + i, addr); |
361 | 379 | ||
362 | /* Setup the control register. */ | 380 | /* Setup the control register. */ |
363 | write_wb_reg(ctrl_base + i, encode_ctrl_reg(info->ctrl) | 0x1); | 381 | write_wb_reg(ctrl_base + i, ctrl); |
364 | 382 | ||
365 | out: | 383 | out: |
366 | return ret; | 384 | return ret; |
@@ -375,18 +393,15 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
375 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { | 393 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { |
376 | /* Breakpoint */ | 394 | /* Breakpoint */ |
377 | base = ARM_BASE_BCR; | 395 | base = ARM_BASE_BCR; |
378 | slots = __get_cpu_var(bp_on_reg); | 396 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); |
379 | max_slots = core_num_brps - 1; | 397 | max_slots = core_num_brps; |
380 | |||
381 | if (bp_is_single_step(bp)) { | ||
382 | i = max_slots; | ||
383 | slots[i] = NULL; | ||
384 | goto reset; | ||
385 | } | ||
386 | } else { | 398 | } else { |
387 | /* Watchpoint */ | 399 | /* Watchpoint */ |
388 | base = ARM_BASE_WCR; | 400 | if (info->step_ctrl.enabled) |
389 | slots = __get_cpu_var(wp_on_reg); | 401 | base = ARM_BASE_BCR + core_num_brps; |
402 | else | ||
403 | base = ARM_BASE_WCR; | ||
404 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
390 | max_slots = core_num_wrps; | 405 | max_slots = core_num_wrps; |
391 | } | 406 | } |
392 | 407 | ||
@@ -403,7 +418,6 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
403 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) | 418 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) |
404 | return; | 419 | return; |
405 | 420 | ||
406 | reset: | ||
407 | /* Reset the control register. */ | 421 | /* Reset the control register. */ |
408 | write_wb_reg(base + i, 0); | 422 | write_wb_reg(base + i, 0); |
409 | } | 423 | } |
@@ -537,12 +551,23 @@ static int arch_build_bp_info(struct perf_event *bp) | |||
537 | return -EINVAL; | 551 | return -EINVAL; |
538 | } | 552 | } |
539 | 553 | ||
554 | /* | ||
555 | * Breakpoints must be of length 2 (thumb) or 4 (ARM) bytes. | ||
556 | * Watchpoints can be of length 1, 2, 4 or 8 bytes if supported | ||
557 | * by the hardware and must be aligned to the appropriate number of | ||
558 | * bytes. | ||
559 | */ | ||
560 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE && | ||
561 | info->ctrl.len != ARM_BREAKPOINT_LEN_2 && | ||
562 | info->ctrl.len != ARM_BREAKPOINT_LEN_4) | ||
563 | return -EINVAL; | ||
564 | |||
540 | /* Address */ | 565 | /* Address */ |
541 | info->address = bp->attr.bp_addr; | 566 | info->address = bp->attr.bp_addr; |
542 | 567 | ||
543 | /* Privilege */ | 568 | /* Privilege */ |
544 | info->ctrl.privilege = ARM_BREAKPOINT_USER; | 569 | info->ctrl.privilege = ARM_BREAKPOINT_USER; |
545 | if (arch_check_bp_in_kernelspace(bp) && !bp_is_single_step(bp)) | 570 | if (arch_check_bp_in_kernelspace(bp)) |
546 | info->ctrl.privilege |= ARM_BREAKPOINT_PRIV; | 571 | info->ctrl.privilege |= ARM_BREAKPOINT_PRIV; |
547 | 572 | ||
548 | /* Enabled? */ | 573 | /* Enabled? */ |
@@ -561,7 +586,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
561 | { | 586 | { |
562 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 587 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
563 | int ret = 0; | 588 | int ret = 0; |
564 | u32 bytelen, max_len, offset, alignment_mask = 0x3; | 589 | u32 offset, alignment_mask = 0x3; |
565 | 590 | ||
566 | /* Build the arch_hw_breakpoint. */ | 591 | /* Build the arch_hw_breakpoint. */ |
567 | ret = arch_build_bp_info(bp); | 592 | ret = arch_build_bp_info(bp); |
@@ -571,84 +596,85 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
571 | /* Check address alignment. */ | 596 | /* Check address alignment. */ |
572 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) | 597 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) |
573 | alignment_mask = 0x7; | 598 | alignment_mask = 0x7; |
574 | if (info->address & alignment_mask) { | 599 | offset = info->address & alignment_mask; |
575 | /* | 600 | switch (offset) { |
576 | * Try to fix the alignment. This may result in a length | 601 | case 0: |
577 | * that is too large, so we must check for that. | 602 | /* Aligned */ |
578 | */ | 603 | break; |
579 | bytelen = get_hbp_len(info->ctrl.len); | 604 | case 1: |
580 | max_len = info->ctrl.type == ARM_BREAKPOINT_EXECUTE ? 4 : | 605 | /* Allow single byte watchpoint. */ |
581 | max_watchpoint_len; | 606 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) |
582 | 607 | break; | |
583 | if (max_len >= 8) | 608 | case 2: |
584 | offset = info->address & 0x7; | 609 | /* Allow halfword watchpoints and breakpoints. */ |
585 | else | 610 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_2) |
586 | offset = info->address & 0x3; | 611 | break; |
587 | 612 | default: | |
588 | if (bytelen > (1 << ((max_len - (offset + 1)) >> 1))) { | 613 | ret = -EINVAL; |
589 | ret = -EFBIG; | 614 | goto out; |
590 | goto out; | ||
591 | } | ||
592 | |||
593 | info->ctrl.len <<= offset; | ||
594 | info->address &= ~offset; | ||
595 | |||
596 | pr_debug("breakpoint alignment fixup: length = 0x%x, " | ||
597 | "address = 0x%x\n", info->ctrl.len, info->address); | ||
598 | } | 615 | } |
599 | 616 | ||
617 | info->address &= ~alignment_mask; | ||
618 | info->ctrl.len <<= offset; | ||
619 | |||
600 | /* | 620 | /* |
601 | * Currently we rely on an overflow handler to take | 621 | * Currently we rely on an overflow handler to take |
602 | * care of single-stepping the breakpoint when it fires. | 622 | * care of single-stepping the breakpoint when it fires. |
603 | * In the case of userspace breakpoints on a core with V7 debug, | 623 | * In the case of userspace breakpoints on a core with V7 debug, |
604 | * we can use the mismatch feature as a poor-man's hardware single-step. | 624 | * we can use the mismatch feature as a poor-man's hardware |
625 | * single-step, but this only works for per-task breakpoints. | ||
605 | */ | 626 | */ |
606 | if (WARN_ONCE(!bp->overflow_handler && | 627 | if (WARN_ONCE(!bp->overflow_handler && |
607 | (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_bps()), | 628 | (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps() |
629 | || !bp->hw.bp_target), | ||
608 | "overflow handler required but none found")) { | 630 | "overflow handler required but none found")) { |
609 | ret = -EINVAL; | 631 | ret = -EINVAL; |
610 | goto out; | ||
611 | } | 632 | } |
612 | out: | 633 | out: |
613 | return ret; | 634 | return ret; |
614 | } | 635 | } |
615 | 636 | ||
616 | static void update_mismatch_flag(int idx, int flag) | 637 | /* |
638 | * Enable/disable single-stepping over the breakpoint bp at address addr. | ||
639 | */ | ||
640 | static void enable_single_step(struct perf_event *bp, u32 addr) | ||
617 | { | 641 | { |
618 | struct perf_event *bp = __get_cpu_var(bp_on_reg[idx]); | 642 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
619 | struct arch_hw_breakpoint *info; | ||
620 | |||
621 | if (bp == NULL) | ||
622 | return; | ||
623 | 643 | ||
624 | info = counter_arch_bp(bp); | 644 | arch_uninstall_hw_breakpoint(bp); |
645 | info->step_ctrl.mismatch = 1; | ||
646 | info->step_ctrl.len = ARM_BREAKPOINT_LEN_4; | ||
647 | info->step_ctrl.type = ARM_BREAKPOINT_EXECUTE; | ||
648 | info->step_ctrl.privilege = info->ctrl.privilege; | ||
649 | info->step_ctrl.enabled = 1; | ||
650 | info->trigger = addr; | ||
651 | arch_install_hw_breakpoint(bp); | ||
652 | } | ||
625 | 653 | ||
626 | /* Update the mismatch field to enter/exit `single-step' mode */ | 654 | static void disable_single_step(struct perf_event *bp) |
627 | if (!bp->overflow_handler && info->ctrl.mismatch != flag) { | 655 | { |
628 | info->ctrl.mismatch = flag; | 656 | arch_uninstall_hw_breakpoint(bp); |
629 | write_wb_reg(ARM_BASE_BCR + idx, encode_ctrl_reg(info->ctrl) | 0x1); | 657 | counter_arch_bp(bp)->step_ctrl.enabled = 0; |
630 | } | 658 | arch_install_hw_breakpoint(bp); |
631 | } | 659 | } |
632 | 660 | ||
633 | static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | 661 | static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) |
634 | { | 662 | { |
635 | int i; | 663 | int i; |
636 | struct perf_event *bp, **slots = __get_cpu_var(wp_on_reg); | 664 | struct perf_event *wp, **slots; |
637 | struct arch_hw_breakpoint *info; | 665 | struct arch_hw_breakpoint *info; |
638 | struct perf_event_attr attr; | 666 | |
667 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
639 | 668 | ||
640 | /* Without a disassembler, we can only handle 1 watchpoint. */ | 669 | /* Without a disassembler, we can only handle 1 watchpoint. */ |
641 | BUG_ON(core_num_wrps > 1); | 670 | BUG_ON(core_num_wrps > 1); |
642 | 671 | ||
643 | hw_breakpoint_init(&attr); | ||
644 | attr.bp_addr = regs->ARM_pc & ~0x3; | ||
645 | attr.bp_len = HW_BREAKPOINT_LEN_4; | ||
646 | attr.bp_type = HW_BREAKPOINT_X; | ||
647 | |||
648 | for (i = 0; i < core_num_wrps; ++i) { | 672 | for (i = 0; i < core_num_wrps; ++i) { |
649 | rcu_read_lock(); | 673 | rcu_read_lock(); |
650 | 674 | ||
651 | if (slots[i] == NULL) { | 675 | wp = slots[i]; |
676 | |||
677 | if (wp == NULL) { | ||
652 | rcu_read_unlock(); | 678 | rcu_read_unlock(); |
653 | continue; | 679 | continue; |
654 | } | 680 | } |
@@ -658,24 +684,51 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | |||
658 | * single watchpoint, we can set the trigger to the lowest | 684 | * single watchpoint, we can set the trigger to the lowest |
659 | * possible faulting address. | 685 | * possible faulting address. |
660 | */ | 686 | */ |
661 | info = counter_arch_bp(slots[i]); | 687 | info = counter_arch_bp(wp); |
662 | info->trigger = slots[i]->attr.bp_addr; | 688 | info->trigger = wp->attr.bp_addr; |
663 | pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); | 689 | pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); |
664 | perf_bp_event(slots[i], regs); | 690 | perf_bp_event(wp, regs); |
665 | 691 | ||
666 | /* | 692 | /* |
667 | * If no overflow handler is present, insert a temporary | 693 | * If no overflow handler is present, insert a temporary |
668 | * mismatch breakpoint so we can single-step over the | 694 | * mismatch breakpoint so we can single-step over the |
669 | * watchpoint trigger. | 695 | * watchpoint trigger. |
670 | */ | 696 | */ |
671 | if (!slots[i]->overflow_handler) { | 697 | if (!wp->overflow_handler) |
672 | bp = register_user_hw_breakpoint(&attr, | 698 | enable_single_step(wp, instruction_pointer(regs)); |
673 | wp_single_step_handler, | 699 | |
674 | current); | 700 | rcu_read_unlock(); |
675 | counter_arch_bp(bp)->suspended_wp = slots[i]; | 701 | } |
676 | perf_event_disable(slots[i]); | 702 | } |
677 | } | ||
678 | 703 | ||
704 | static void watchpoint_single_step_handler(unsigned long pc) | ||
705 | { | ||
706 | int i; | ||
707 | struct perf_event *wp, **slots; | ||
708 | struct arch_hw_breakpoint *info; | ||
709 | |||
710 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
711 | |||
712 | for (i = 0; i < core_num_reserved_brps; ++i) { | ||
713 | rcu_read_lock(); | ||
714 | |||
715 | wp = slots[i]; | ||
716 | |||
717 | if (wp == NULL) | ||
718 | goto unlock; | ||
719 | |||
720 | info = counter_arch_bp(wp); | ||
721 | if (!info->step_ctrl.enabled) | ||
722 | goto unlock; | ||
723 | |||
724 | /* | ||
725 | * Restore the original watchpoint if we've completed the | ||
726 | * single-step. | ||
727 | */ | ||
728 | if (info->trigger != pc) | ||
729 | disable_single_step(wp); | ||
730 | |||
731 | unlock: | ||
679 | rcu_read_unlock(); | 732 | rcu_read_unlock(); |
680 | } | 733 | } |
681 | } | 734 | } |
@@ -683,62 +736,69 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | |||
683 | static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) | 736 | static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) |
684 | { | 737 | { |
685 | int i; | 738 | int i; |
686 | int mismatch; | ||
687 | u32 ctrl_reg, val, addr; | 739 | u32 ctrl_reg, val, addr; |
688 | struct perf_event *bp, **slots = __get_cpu_var(bp_on_reg); | 740 | struct perf_event *bp, **slots; |
689 | struct arch_hw_breakpoint *info; | 741 | struct arch_hw_breakpoint *info; |
690 | struct arch_hw_breakpoint_ctrl ctrl; | 742 | struct arch_hw_breakpoint_ctrl ctrl; |
691 | 743 | ||
744 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); | ||
745 | |||
692 | /* The exception entry code places the amended lr in the PC. */ | 746 | /* The exception entry code places the amended lr in the PC. */ |
693 | addr = regs->ARM_pc; | 747 | addr = regs->ARM_pc; |
694 | 748 | ||
749 | /* Check the currently installed breakpoints first. */ | ||
695 | for (i = 0; i < core_num_brps; ++i) { | 750 | for (i = 0; i < core_num_brps; ++i) { |
696 | rcu_read_lock(); | 751 | rcu_read_lock(); |
697 | 752 | ||
698 | bp = slots[i]; | 753 | bp = slots[i]; |
699 | 754 | ||
700 | if (bp == NULL) { | 755 | if (bp == NULL) |
701 | rcu_read_unlock(); | 756 | goto unlock; |
702 | continue; | ||
703 | } | ||
704 | 757 | ||
705 | mismatch = 0; | 758 | info = counter_arch_bp(bp); |
706 | 759 | ||
707 | /* Check if the breakpoint value matches. */ | 760 | /* Check if the breakpoint value matches. */ |
708 | val = read_wb_reg(ARM_BASE_BVR + i); | 761 | val = read_wb_reg(ARM_BASE_BVR + i); |
709 | if (val != (addr & ~0x3)) | 762 | if (val != (addr & ~0x3)) |
710 | goto unlock; | 763 | goto mismatch; |
711 | 764 | ||
712 | /* Possible match, check the byte address select to confirm. */ | 765 | /* Possible match, check the byte address select to confirm. */ |
713 | ctrl_reg = read_wb_reg(ARM_BASE_BCR + i); | 766 | ctrl_reg = read_wb_reg(ARM_BASE_BCR + i); |
714 | decode_ctrl_reg(ctrl_reg, &ctrl); | 767 | decode_ctrl_reg(ctrl_reg, &ctrl); |
715 | if ((1 << (addr & 0x3)) & ctrl.len) { | 768 | if ((1 << (addr & 0x3)) & ctrl.len) { |
716 | mismatch = 1; | ||
717 | info = counter_arch_bp(bp); | ||
718 | info->trigger = addr; | 769 | info->trigger = addr; |
719 | } | ||
720 | |||
721 | unlock: | ||
722 | if ((mismatch && !info->ctrl.mismatch) || bp_is_single_step(bp)) { | ||
723 | pr_debug("breakpoint fired: address = 0x%x\n", addr); | 770 | pr_debug("breakpoint fired: address = 0x%x\n", addr); |
724 | perf_bp_event(bp, regs); | 771 | perf_bp_event(bp, regs); |
772 | if (!bp->overflow_handler) | ||
773 | enable_single_step(bp, addr); | ||
774 | goto unlock; | ||
725 | } | 775 | } |
726 | 776 | ||
727 | update_mismatch_flag(i, mismatch); | 777 | mismatch: |
778 | /* If we're stepping a breakpoint, it can now be restored. */ | ||
779 | if (info->step_ctrl.enabled) | ||
780 | disable_single_step(bp); | ||
781 | unlock: | ||
728 | rcu_read_unlock(); | 782 | rcu_read_unlock(); |
729 | } | 783 | } |
784 | |||
785 | /* Handle any pending watchpoint single-step breakpoints. */ | ||
786 | watchpoint_single_step_handler(addr); | ||
730 | } | 787 | } |
731 | 788 | ||
732 | /* | 789 | /* |
733 | * Called from either the Data Abort Handler [watchpoint] or the | 790 | * Called from either the Data Abort Handler [watchpoint] or the |
734 | * Prefetch Abort Handler [breakpoint]. | 791 | * Prefetch Abort Handler [breakpoint] with preemption disabled. |
735 | */ | 792 | */ |
736 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | 793 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, |
737 | struct pt_regs *regs) | 794 | struct pt_regs *regs) |
738 | { | 795 | { |
739 | int ret = 1; /* Unhandled fault. */ | 796 | int ret = 0; |
740 | u32 dscr; | 797 | u32 dscr; |
741 | 798 | ||
799 | /* We must be called with preemption disabled. */ | ||
800 | WARN_ON(preemptible()); | ||
801 | |||
742 | /* We only handle watchpoints and hardware breakpoints. */ | 802 | /* We only handle watchpoints and hardware breakpoints. */ |
743 | ARM_DBG_READ(c1, 0, dscr); | 803 | ARM_DBG_READ(c1, 0, dscr); |
744 | 804 | ||
@@ -753,25 +813,47 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
753 | watchpoint_handler(addr, regs); | 813 | watchpoint_handler(addr, regs); |
754 | break; | 814 | break; |
755 | default: | 815 | default: |
756 | goto out; | 816 | ret = 1; /* Unhandled fault. */ |
757 | } | 817 | } |
758 | 818 | ||
759 | ret = 0; | 819 | /* |
760 | out: | 820 | * Re-enable preemption after it was disabled in the |
821 | * low-level exception handling code. | ||
822 | */ | ||
823 | preempt_enable(); | ||
824 | |||
761 | return ret; | 825 | return ret; |
762 | } | 826 | } |
763 | 827 | ||
764 | /* | 828 | /* |
765 | * One-time initialisation. | 829 | * One-time initialisation. |
766 | */ | 830 | */ |
767 | static void __init reset_ctrl_regs(void *unused) | 831 | static void reset_ctrl_regs(void *unused) |
768 | { | 832 | { |
769 | int i; | 833 | int i; |
770 | 834 | ||
835 | /* | ||
836 | * v7 debug contains save and restore registers so that debug state | ||
837 | * can be maintained across low-power modes without leaving | ||
838 | * the debug logic powered up. It is IMPLEMENTATION DEFINED whether | ||
839 | * we can write to the debug registers out of reset, so we must | ||
840 | * unlock the OS Lock Access Register to avoid taking undefined | ||
841 | * instruction exceptions later on. | ||
842 | */ | ||
843 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { | ||
844 | /* | ||
845 | * Unconditionally clear the lock by writing a value | ||
846 | * other than 0xC5ACCE55 to the access register. | ||
847 | */ | ||
848 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); | ||
849 | isb(); | ||
850 | } | ||
851 | |||
771 | if (enable_monitor_mode()) | 852 | if (enable_monitor_mode()) |
772 | return; | 853 | return; |
773 | 854 | ||
774 | for (i = 0; i < core_num_brps; ++i) { | 855 | /* We must also reset any reserved registers. */ |
856 | for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) { | ||
775 | write_wb_reg(ARM_BASE_BCR + i, 0UL); | 857 | write_wb_reg(ARM_BASE_BCR + i, 0UL); |
776 | write_wb_reg(ARM_BASE_BVR + i, 0UL); | 858 | write_wb_reg(ARM_BASE_BVR + i, 0UL); |
777 | } | 859 | } |
@@ -782,45 +864,57 @@ static void __init reset_ctrl_regs(void *unused) | |||
782 | } | 864 | } |
783 | } | 865 | } |
784 | 866 | ||
867 | static int __cpuinit dbg_reset_notify(struct notifier_block *self, | ||
868 | unsigned long action, void *cpu) | ||
869 | { | ||
870 | if (action == CPU_ONLINE) | ||
871 | smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1); | ||
872 | return NOTIFY_OK; | ||
873 | } | ||
874 | |||
875 | static struct notifier_block __cpuinitdata dbg_reset_nb = { | ||
876 | .notifier_call = dbg_reset_notify, | ||
877 | }; | ||
878 | |||
785 | static int __init arch_hw_breakpoint_init(void) | 879 | static int __init arch_hw_breakpoint_init(void) |
786 | { | 880 | { |
787 | int ret = 0; | ||
788 | u32 dscr; | 881 | u32 dscr; |
789 | 882 | ||
790 | debug_arch = get_debug_arch(); | 883 | debug_arch = get_debug_arch(); |
791 | 884 | ||
792 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { | 885 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { |
793 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); | 886 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); |
794 | ret = -ENODEV; | 887 | return 0; |
795 | goto out; | ||
796 | } | 888 | } |
797 | 889 | ||
798 | /* Determine how many BRPs/WRPs are available. */ | 890 | /* Determine how many BRPs/WRPs are available. */ |
799 | core_num_brps = get_num_brps(); | 891 | core_num_brps = get_num_brps(); |
892 | core_num_reserved_brps = get_num_reserved_brps(); | ||
800 | core_num_wrps = get_num_wrps(); | 893 | core_num_wrps = get_num_wrps(); |
801 | 894 | ||
802 | pr_info("found %d breakpoint and %d watchpoint registers.\n", | 895 | pr_info("found %d breakpoint and %d watchpoint registers.\n", |
803 | core_num_brps, core_num_wrps); | 896 | core_num_brps + core_num_reserved_brps, core_num_wrps); |
804 | 897 | ||
805 | if (core_has_mismatch_bps()) | 898 | if (core_num_reserved_brps) |
806 | pr_info("1 breakpoint reserved for watchpoint single-step.\n"); | 899 | pr_info("%d breakpoint(s) reserved for watchpoint " |
900 | "single-step.\n", core_num_reserved_brps); | ||
807 | 901 | ||
808 | ARM_DBG_READ(c1, 0, dscr); | 902 | ARM_DBG_READ(c1, 0, dscr); |
809 | if (dscr & ARM_DSCR_HDBGEN) { | 903 | if (dscr & ARM_DSCR_HDBGEN) { |
810 | pr_warning("halting debug mode enabled. Assuming maximum " | 904 | pr_warning("halting debug mode enabled. Assuming maximum " |
811 | "watchpoint size of 4 bytes."); | 905 | "watchpoint size of 4 bytes."); |
812 | } else { | 906 | } else { |
813 | /* Work out the maximum supported watchpoint length. */ | ||
814 | max_watchpoint_len = get_max_wp_len(); | ||
815 | pr_info("maximum watchpoint size is %u bytes.\n", | ||
816 | max_watchpoint_len); | ||
817 | |||
818 | /* | 907 | /* |
819 | * Reset the breakpoint resources. We assume that a halting | 908 | * Reset the breakpoint resources. We assume that a halting |
820 | * debugger will leave the world in a nice state for us. | 909 | * debugger will leave the world in a nice state for us. |
821 | */ | 910 | */ |
822 | smp_call_function(reset_ctrl_regs, NULL, 1); | 911 | smp_call_function(reset_ctrl_regs, NULL, 1); |
823 | reset_ctrl_regs(NULL); | 912 | reset_ctrl_regs(NULL); |
913 | |||
914 | /* Work out the maximum supported watchpoint length. */ | ||
915 | max_watchpoint_len = get_max_wp_len(); | ||
916 | pr_info("maximum watchpoint size is %u bytes.\n", | ||
917 | max_watchpoint_len); | ||
824 | } | 918 | } |
825 | 919 | ||
826 | /* Register debug fault handler. */ | 920 | /* Register debug fault handler. */ |
@@ -829,8 +923,9 @@ static int __init arch_hw_breakpoint_init(void) | |||
829 | hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, | 923 | hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, |
830 | "breakpoint debug exception"); | 924 | "breakpoint debug exception"); |
831 | 925 | ||
832 | out: | 926 | /* Register hotplug notifier. */ |
833 | return ret; | 927 | register_cpu_notifier(&dbg_reset_nb); |
928 | return 0; | ||
834 | } | 929 | } |
835 | arch_initcall(arch_hw_breakpoint_init); | 930 | arch_initcall(arch_hw_breakpoint_init); |
836 | 931 | ||
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 36ad3be4692a..6d616333340f 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/list.h> | 35 | #include <linux/list.h> |
36 | #include <linux/kallsyms.h> | 36 | #include <linux/kallsyms.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/ftrace.h> | ||
38 | 39 | ||
39 | #include <asm/system.h> | 40 | #include <asm/system.h> |
40 | #include <asm/mach/irq.h> | 41 | #include <asm/mach/irq.h> |
@@ -105,7 +106,8 @@ unlock: | |||
105 | * come via this function. Instead, they should provide their | 106 | * come via this function. Instead, they should provide their |
106 | * own 'handler' | 107 | * own 'handler' |
107 | */ | 108 | */ |
108 | asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) | 109 | asmlinkage void __exception_irq_entry |
110 | asm_do_IRQ(unsigned int irq, struct pt_regs *regs) | ||
109 | { | 111 | { |
110 | struct pt_regs *old_regs = set_irq_regs(regs); | 112 | struct pt_regs *old_regs = set_irq_regs(regs); |
111 | 113 | ||
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index b63b528f22a6..7fa3bb0d2397 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S | |||
@@ -19,6 +19,14 @@ | |||
19 | #include <asm/thread_info.h> | 19 | #include <asm/thread_info.h> |
20 | #include <asm/asm-offsets.h> | 20 | #include <asm/asm-offsets.h> |
21 | 21 | ||
22 | #if defined(CONFIG_CPU_PJ4) | ||
23 | #define PJ4(code...) code | ||
24 | #define XSC(code...) | ||
25 | #else | ||
26 | #define PJ4(code...) | ||
27 | #define XSC(code...) code | ||
28 | #endif | ||
29 | |||
22 | #define MMX_WR0 (0x00) | 30 | #define MMX_WR0 (0x00) |
23 | #define MMX_WR1 (0x08) | 31 | #define MMX_WR1 (0x08) |
24 | #define MMX_WR2 (0x10) | 32 | #define MMX_WR2 (0x10) |
@@ -58,11 +66,17 @@ | |||
58 | 66 | ||
59 | ENTRY(iwmmxt_task_enable) | 67 | ENTRY(iwmmxt_task_enable) |
60 | 68 | ||
61 | mrc p15, 0, r2, c15, c1, 0 | 69 | XSC(mrc p15, 0, r2, c15, c1, 0) |
62 | tst r2, #0x3 @ CP0 and CP1 accessible? | 70 | PJ4(mrc p15, 0, r2, c1, c0, 2) |
71 | @ CP0 and CP1 accessible? | ||
72 | XSC(tst r2, #0x3) | ||
73 | PJ4(tst r2, #0xf) | ||
63 | movne pc, lr @ if so no business here | 74 | movne pc, lr @ if so no business here |
64 | orr r2, r2, #0x3 @ enable access to CP0 and CP1 | 75 | @ enable access to CP0 and CP1 |
65 | mcr p15, 0, r2, c15, c1, 0 | 76 | XSC(orr r2, r2, #0x3) |
77 | XSC(mcr p15, 0, r2, c15, c1, 0) | ||
78 | PJ4(orr r2, r2, #0xf) | ||
79 | PJ4(mcr p15, 0, r2, c1, c0, 2) | ||
66 | 80 | ||
67 | ldr r3, =concan_owner | 81 | ldr r3, =concan_owner |
68 | add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area | 82 | add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area |
@@ -179,17 +193,26 @@ ENTRY(iwmmxt_task_disable) | |||
179 | teqne r1, r2 @ or specified one? | 193 | teqne r1, r2 @ or specified one? |
180 | bne 1f @ no: quit | 194 | bne 1f @ no: quit |
181 | 195 | ||
182 | mrc p15, 0, r4, c15, c1, 0 | 196 | @ enable access to CP0 and CP1 |
183 | orr r4, r4, #0x3 @ enable access to CP0 and CP1 | 197 | XSC(mrc p15, 0, r4, c15, c1, 0) |
184 | mcr p15, 0, r4, c15, c1, 0 | 198 | XSC(orr r4, r4, #0xf) |
199 | XSC(mcr p15, 0, r4, c15, c1, 0) | ||
200 | PJ4(mrc p15, 0, r4, c1, c0, 2) | ||
201 | PJ4(orr r4, r4, #0x3) | ||
202 | PJ4(mcr p15, 0, r4, c1, c0, 2) | ||
203 | |||
185 | mov r0, #0 @ nothing to load | 204 | mov r0, #0 @ nothing to load |
186 | str r0, [r3] @ no more current owner | 205 | str r0, [r3] @ no more current owner |
187 | mrc p15, 0, r2, c2, c0, 0 | 206 | mrc p15, 0, r2, c2, c0, 0 |
188 | mov r2, r2 @ cpwait | 207 | mov r2, r2 @ cpwait |
189 | bl concan_save | 208 | bl concan_save |
190 | 209 | ||
191 | bic r4, r4, #0x3 @ disable access to CP0 and CP1 | 210 | @ disable access to CP0 and CP1 |
192 | mcr p15, 0, r4, c15, c1, 0 | 211 | XSC(bic r4, r4, #0x3) |
212 | XSC(mcr p15, 0, r4, c15, c1, 0) | ||
213 | PJ4(bic r4, r4, #0xf) | ||
214 | PJ4(mcr p15, 0, r4, c1, c0, 2) | ||
215 | |||
193 | mrc p15, 0, r2, c2, c0, 0 | 216 | mrc p15, 0, r2, c2, c0, 0 |
194 | mov r2, r2 @ cpwait | 217 | mov r2, r2 @ cpwait |
195 | 218 | ||
@@ -277,8 +300,11 @@ ENTRY(iwmmxt_task_restore) | |||
277 | */ | 300 | */ |
278 | ENTRY(iwmmxt_task_switch) | 301 | ENTRY(iwmmxt_task_switch) |
279 | 302 | ||
280 | mrc p15, 0, r1, c15, c1, 0 | 303 | XSC(mrc p15, 0, r1, c15, c1, 0) |
281 | tst r1, #0x3 @ CP0 and CP1 accessible? | 304 | PJ4(mrc p15, 0, r1, c1, c0, 2) |
305 | @ CP0 and CP1 accessible? | ||
306 | XSC(tst r1, #0x3) | ||
307 | PJ4(tst r1, #0xf) | ||
282 | bne 1f @ yes: block them for next task | 308 | bne 1f @ yes: block them for next task |
283 | 309 | ||
284 | ldr r2, =concan_owner | 310 | ldr r2, =concan_owner |
@@ -287,8 +313,11 @@ ENTRY(iwmmxt_task_switch) | |||
287 | teq r2, r3 @ next task owns it? | 313 | teq r2, r3 @ next task owns it? |
288 | movne pc, lr @ no: leave Concan disabled | 314 | movne pc, lr @ no: leave Concan disabled |
289 | 315 | ||
290 | 1: eor r1, r1, #3 @ flip Concan access | 316 | 1: @ flip Conan access |
291 | mcr p15, 0, r1, c15, c1, 0 | 317 | XSC(eor r1, r1, #0x3) |
318 | XSC(mcr p15, 0, r1, c15, c1, 0) | ||
319 | PJ4(eor r1, r1, #0xf) | ||
320 | PJ4(mcr p15, 0, r1, c1, c0, 2) | ||
292 | 321 | ||
293 | mrc p15, 0, r1, c2, c0, 0 | 322 | mrc p15, 0, r1, c2, c0, 0 |
294 | sub pc, lr, r1, lsr #32 @ cpwait and return | 323 | sub pc, lr, r1, lsr #32 @ cpwait and return |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 07a50357492a..624e2a5de2b3 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -4,9 +4,7 @@ | |||
4 | * ARM performance counter support. | 4 | * ARM performance counter support. |
5 | * | 5 | * |
6 | * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles | 6 | * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles |
7 | * | 7 | * Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com> |
8 | * ARMv7 support: Jean Pihet <jpihet@mvista.com> | ||
9 | * 2010 (c) MontaVista Software, LLC. | ||
10 | * | 8 | * |
11 | * This code is based on the sparc64 perf event code, which is in turn based | 9 | * This code is based on the sparc64 perf event code, which is in turn based |
12 | * on the x86 code. Callchain code is based on the ARM OProfile backtrace | 10 | * on the x86 code. Callchain code is based on the ARM OProfile backtrace |
@@ -34,7 +32,7 @@ static struct platform_device *pmu_device; | |||
34 | * Hardware lock to serialize accesses to PMU registers. Needed for the | 32 | * Hardware lock to serialize accesses to PMU registers. Needed for the |
35 | * read/modify/write sequences. | 33 | * read/modify/write sequences. |
36 | */ | 34 | */ |
37 | DEFINE_SPINLOCK(pmu_lock); | 35 | static DEFINE_RAW_SPINLOCK(pmu_lock); |
38 | 36 | ||
39 | /* | 37 | /* |
40 | * ARMv6 supports a maximum of 3 events, starting from index 1. If we add | 38 | * ARMv6 supports a maximum of 3 events, starting from index 1. If we add |
@@ -67,31 +65,25 @@ struct cpu_hw_events { | |||
67 | */ | 65 | */ |
68 | unsigned long active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; | 66 | unsigned long active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; |
69 | }; | 67 | }; |
70 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); | 68 | static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); |
71 | |||
72 | /* PMU names. */ | ||
73 | static const char *arm_pmu_names[] = { | ||
74 | [ARM_PERF_PMU_ID_XSCALE1] = "xscale1", | ||
75 | [ARM_PERF_PMU_ID_XSCALE2] = "xscale2", | ||
76 | [ARM_PERF_PMU_ID_V6] = "v6", | ||
77 | [ARM_PERF_PMU_ID_V6MP] = "v6mpcore", | ||
78 | [ARM_PERF_PMU_ID_CA8] = "ARMv7 Cortex-A8", | ||
79 | [ARM_PERF_PMU_ID_CA9] = "ARMv7 Cortex-A9", | ||
80 | }; | ||
81 | 69 | ||
82 | struct arm_pmu { | 70 | struct arm_pmu { |
83 | enum arm_perf_pmu_ids id; | 71 | enum arm_perf_pmu_ids id; |
72 | const char *name; | ||
84 | irqreturn_t (*handle_irq)(int irq_num, void *dev); | 73 | irqreturn_t (*handle_irq)(int irq_num, void *dev); |
85 | void (*enable)(struct hw_perf_event *evt, int idx); | 74 | void (*enable)(struct hw_perf_event *evt, int idx); |
86 | void (*disable)(struct hw_perf_event *evt, int idx); | 75 | void (*disable)(struct hw_perf_event *evt, int idx); |
87 | int (*event_map)(int evt); | ||
88 | u64 (*raw_event)(u64); | ||
89 | int (*get_event_idx)(struct cpu_hw_events *cpuc, | 76 | int (*get_event_idx)(struct cpu_hw_events *cpuc, |
90 | struct hw_perf_event *hwc); | 77 | struct hw_perf_event *hwc); |
91 | u32 (*read_counter)(int idx); | 78 | u32 (*read_counter)(int idx); |
92 | void (*write_counter)(int idx, u32 val); | 79 | void (*write_counter)(int idx, u32 val); |
93 | void (*start)(void); | 80 | void (*start)(void); |
94 | void (*stop)(void); | 81 | void (*stop)(void); |
82 | const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX] | ||
83 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
84 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | ||
85 | const unsigned (*event_map)[PERF_COUNT_HW_MAX]; | ||
86 | u32 raw_event_mask; | ||
95 | int num_events; | 87 | int num_events; |
96 | u64 max_period; | 88 | u64 max_period; |
97 | }; | 89 | }; |
@@ -136,10 +128,6 @@ EXPORT_SYMBOL_GPL(perf_num_counters); | |||
136 | 128 | ||
137 | #define CACHE_OP_UNSUPPORTED 0xFFFF | 129 | #define CACHE_OP_UNSUPPORTED 0xFFFF |
138 | 130 | ||
139 | static unsigned armpmu_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
140 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
141 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | ||
142 | |||
143 | static int | 131 | static int |
144 | armpmu_map_cache_event(u64 config) | 132 | armpmu_map_cache_event(u64 config) |
145 | { | 133 | { |
@@ -157,7 +145,7 @@ armpmu_map_cache_event(u64 config) | |||
157 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) | 145 | if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) |
158 | return -EINVAL; | 146 | return -EINVAL; |
159 | 147 | ||
160 | ret = (int)armpmu_perf_cache_map[cache_type][cache_op][cache_result]; | 148 | ret = (int)(*armpmu->cache_map)[cache_type][cache_op][cache_result]; |
161 | 149 | ||
162 | if (ret == CACHE_OP_UNSUPPORTED) | 150 | if (ret == CACHE_OP_UNSUPPORTED) |
163 | return -ENOENT; | 151 | return -ENOENT; |
@@ -166,6 +154,19 @@ armpmu_map_cache_event(u64 config) | |||
166 | } | 154 | } |
167 | 155 | ||
168 | static int | 156 | static int |
157 | armpmu_map_event(u64 config) | ||
158 | { | ||
159 | int mapping = (*armpmu->event_map)[config]; | ||
160 | return mapping == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : mapping; | ||
161 | } | ||
162 | |||
163 | static int | ||
164 | armpmu_map_raw_event(u64 config) | ||
165 | { | ||
166 | return (int)(config & armpmu->raw_event_mask); | ||
167 | } | ||
168 | |||
169 | static int | ||
169 | armpmu_event_set_period(struct perf_event *event, | 170 | armpmu_event_set_period(struct perf_event *event, |
170 | struct hw_perf_event *hwc, | 171 | struct hw_perf_event *hwc, |
171 | int idx) | 172 | int idx) |
@@ -458,11 +459,11 @@ __hw_perf_event_init(struct perf_event *event) | |||
458 | 459 | ||
459 | /* Decode the generic type into an ARM event identifier. */ | 460 | /* Decode the generic type into an ARM event identifier. */ |
460 | if (PERF_TYPE_HARDWARE == event->attr.type) { | 461 | if (PERF_TYPE_HARDWARE == event->attr.type) { |
461 | mapping = armpmu->event_map(event->attr.config); | 462 | mapping = armpmu_map_event(event->attr.config); |
462 | } else if (PERF_TYPE_HW_CACHE == event->attr.type) { | 463 | } else if (PERF_TYPE_HW_CACHE == event->attr.type) { |
463 | mapping = armpmu_map_cache_event(event->attr.config); | 464 | mapping = armpmu_map_cache_event(event->attr.config); |
464 | } else if (PERF_TYPE_RAW == event->attr.type) { | 465 | } else if (PERF_TYPE_RAW == event->attr.type) { |
465 | mapping = armpmu->raw_event(event->attr.config); | 466 | mapping = armpmu_map_raw_event(event->attr.config); |
466 | } else { | 467 | } else { |
467 | pr_debug("event type %x not supported\n", event->attr.type); | 468 | pr_debug("event type %x not supported\n", event->attr.type); |
468 | return -EOPNOTSUPP; | 469 | return -EOPNOTSUPP; |
@@ -603,2366 +604,10 @@ static struct pmu pmu = { | |||
603 | .read = armpmu_read, | 604 | .read = armpmu_read, |
604 | }; | 605 | }; |
605 | 606 | ||
606 | /* | 607 | /* Include the PMU-specific implementations. */ |
607 | * ARMv6 Performance counter handling code. | 608 | #include "perf_event_xscale.c" |
608 | * | 609 | #include "perf_event_v6.c" |
609 | * ARMv6 has 2 configurable performance counters and a single cycle counter. | 610 | #include "perf_event_v7.c" |
610 | * They all share a single reset bit but can be written to zero so we can use | ||
611 | * that for a reset. | ||
612 | * | ||
613 | * The counters can't be individually enabled or disabled so when we remove | ||
614 | * one event and replace it with another we could get spurious counts from the | ||
615 | * wrong event. However, we can take advantage of the fact that the | ||
616 | * performance counters can export events to the event bus, and the event bus | ||
617 | * itself can be monitored. This requires that we *don't* export the events to | ||
618 | * the event bus. The procedure for disabling a configurable counter is: | ||
619 | * - change the counter to count the ETMEXTOUT[0] signal (0x20). This | ||
620 | * effectively stops the counter from counting. | ||
621 | * - disable the counter's interrupt generation (each counter has it's | ||
622 | * own interrupt enable bit). | ||
623 | * Once stopped, the counter value can be written as 0 to reset. | ||
624 | * | ||
625 | * To enable a counter: | ||
626 | * - enable the counter's interrupt generation. | ||
627 | * - set the new event type. | ||
628 | * | ||
629 | * Note: the dedicated cycle counter only counts cycles and can't be | ||
630 | * enabled/disabled independently of the others. When we want to disable the | ||
631 | * cycle counter, we have to just disable the interrupt reporting and start | ||
632 | * ignoring that counter. When re-enabling, we have to reset the value and | ||
633 | * enable the interrupt. | ||
634 | */ | ||
635 | |||
636 | enum armv6_perf_types { | ||
637 | ARMV6_PERFCTR_ICACHE_MISS = 0x0, | ||
638 | ARMV6_PERFCTR_IBUF_STALL = 0x1, | ||
639 | ARMV6_PERFCTR_DDEP_STALL = 0x2, | ||
640 | ARMV6_PERFCTR_ITLB_MISS = 0x3, | ||
641 | ARMV6_PERFCTR_DTLB_MISS = 0x4, | ||
642 | ARMV6_PERFCTR_BR_EXEC = 0x5, | ||
643 | ARMV6_PERFCTR_BR_MISPREDICT = 0x6, | ||
644 | ARMV6_PERFCTR_INSTR_EXEC = 0x7, | ||
645 | ARMV6_PERFCTR_DCACHE_HIT = 0x9, | ||
646 | ARMV6_PERFCTR_DCACHE_ACCESS = 0xA, | ||
647 | ARMV6_PERFCTR_DCACHE_MISS = 0xB, | ||
648 | ARMV6_PERFCTR_DCACHE_WBACK = 0xC, | ||
649 | ARMV6_PERFCTR_SW_PC_CHANGE = 0xD, | ||
650 | ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF, | ||
651 | ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10, | ||
652 | ARMV6_PERFCTR_LSU_FULL_STALL = 0x11, | ||
653 | ARMV6_PERFCTR_WBUF_DRAINED = 0x12, | ||
654 | ARMV6_PERFCTR_CPU_CYCLES = 0xFF, | ||
655 | ARMV6_PERFCTR_NOP = 0x20, | ||
656 | }; | ||
657 | |||
658 | enum armv6_counters { | ||
659 | ARMV6_CYCLE_COUNTER = 1, | ||
660 | ARMV6_COUNTER0, | ||
661 | ARMV6_COUNTER1, | ||
662 | }; | ||
663 | |||
664 | /* | ||
665 | * The hardware events that we support. We do support cache operations but | ||
666 | * we have harvard caches and no way to combine instruction and data | ||
667 | * accesses/misses in hardware. | ||
668 | */ | ||
669 | static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = { | ||
670 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES, | ||
671 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC, | ||
672 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
673 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
674 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC, | ||
675 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT, | ||
676 | [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, | ||
677 | }; | ||
678 | |||
679 | static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
680 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
681 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
682 | [C(L1D)] = { | ||
683 | /* | ||
684 | * The performance counters don't differentiate between read | ||
685 | * and write accesses/misses so this isn't strictly correct, | ||
686 | * but it's the best we can do. Writes and reads get | ||
687 | * combined. | ||
688 | */ | ||
689 | [C(OP_READ)] = { | ||
690 | [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS, | ||
691 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS, | ||
692 | }, | ||
693 | [C(OP_WRITE)] = { | ||
694 | [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS, | ||
695 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS, | ||
696 | }, | ||
697 | [C(OP_PREFETCH)] = { | ||
698 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
699 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
700 | }, | ||
701 | }, | ||
702 | [C(L1I)] = { | ||
703 | [C(OP_READ)] = { | ||
704 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
705 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS, | ||
706 | }, | ||
707 | [C(OP_WRITE)] = { | ||
708 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
709 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS, | ||
710 | }, | ||
711 | [C(OP_PREFETCH)] = { | ||
712 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
713 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
714 | }, | ||
715 | }, | ||
716 | [C(LL)] = { | ||
717 | [C(OP_READ)] = { | ||
718 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
719 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
720 | }, | ||
721 | [C(OP_WRITE)] = { | ||
722 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
723 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
724 | }, | ||
725 | [C(OP_PREFETCH)] = { | ||
726 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
727 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
728 | }, | ||
729 | }, | ||
730 | [C(DTLB)] = { | ||
731 | /* | ||
732 | * The ARM performance counters can count micro DTLB misses, | ||
733 | * micro ITLB misses and main TLB misses. There isn't an event | ||
734 | * for TLB misses, so use the micro misses here and if users | ||
735 | * want the main TLB misses they can use a raw counter. | ||
736 | */ | ||
737 | [C(OP_READ)] = { | ||
738 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
739 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS, | ||
740 | }, | ||
741 | [C(OP_WRITE)] = { | ||
742 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
743 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS, | ||
744 | }, | ||
745 | [C(OP_PREFETCH)] = { | ||
746 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
747 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
748 | }, | ||
749 | }, | ||
750 | [C(ITLB)] = { | ||
751 | [C(OP_READ)] = { | ||
752 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
753 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS, | ||
754 | }, | ||
755 | [C(OP_WRITE)] = { | ||
756 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
757 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS, | ||
758 | }, | ||
759 | [C(OP_PREFETCH)] = { | ||
760 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
761 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
762 | }, | ||
763 | }, | ||
764 | [C(BPU)] = { | ||
765 | [C(OP_READ)] = { | ||
766 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
767 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
768 | }, | ||
769 | [C(OP_WRITE)] = { | ||
770 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
771 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
772 | }, | ||
773 | [C(OP_PREFETCH)] = { | ||
774 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
775 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
776 | }, | ||
777 | }, | ||
778 | }; | ||
779 | |||
780 | enum armv6mpcore_perf_types { | ||
781 | ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0, | ||
782 | ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1, | ||
783 | ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2, | ||
784 | ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3, | ||
785 | ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4, | ||
786 | ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5, | ||
787 | ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6, | ||
788 | ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7, | ||
789 | ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8, | ||
790 | ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA, | ||
791 | ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB, | ||
792 | ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC, | ||
793 | ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD, | ||
794 | ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE, | ||
795 | ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF, | ||
796 | ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10, | ||
797 | ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11, | ||
798 | ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12, | ||
799 | ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13, | ||
800 | ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF, | ||
801 | }; | ||
802 | |||
803 | /* | ||
804 | * The hardware events that we support. We do support cache operations but | ||
805 | * we have harvard caches and no way to combine instruction and data | ||
806 | * accesses/misses in hardware. | ||
807 | */ | ||
808 | static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = { | ||
809 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES, | ||
810 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC, | ||
811 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
812 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
813 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC, | ||
814 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT, | ||
815 | [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, | ||
816 | }; | ||
817 | |||
818 | static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
819 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
820 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
821 | [C(L1D)] = { | ||
822 | [C(OP_READ)] = { | ||
823 | [C(RESULT_ACCESS)] = | ||
824 | ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS, | ||
825 | [C(RESULT_MISS)] = | ||
826 | ARMV6MPCORE_PERFCTR_DCACHE_RDMISS, | ||
827 | }, | ||
828 | [C(OP_WRITE)] = { | ||
829 | [C(RESULT_ACCESS)] = | ||
830 | ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS, | ||
831 | [C(RESULT_MISS)] = | ||
832 | ARMV6MPCORE_PERFCTR_DCACHE_WRMISS, | ||
833 | }, | ||
834 | [C(OP_PREFETCH)] = { | ||
835 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
836 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
837 | }, | ||
838 | }, | ||
839 | [C(L1I)] = { | ||
840 | [C(OP_READ)] = { | ||
841 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
842 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS, | ||
843 | }, | ||
844 | [C(OP_WRITE)] = { | ||
845 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
846 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS, | ||
847 | }, | ||
848 | [C(OP_PREFETCH)] = { | ||
849 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
850 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
851 | }, | ||
852 | }, | ||
853 | [C(LL)] = { | ||
854 | [C(OP_READ)] = { | ||
855 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
856 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
857 | }, | ||
858 | [C(OP_WRITE)] = { | ||
859 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
860 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
861 | }, | ||
862 | [C(OP_PREFETCH)] = { | ||
863 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
864 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
865 | }, | ||
866 | }, | ||
867 | [C(DTLB)] = { | ||
868 | /* | ||
869 | * The ARM performance counters can count micro DTLB misses, | ||
870 | * micro ITLB misses and main TLB misses. There isn't an event | ||
871 | * for TLB misses, so use the micro misses here and if users | ||
872 | * want the main TLB misses they can use a raw counter. | ||
873 | */ | ||
874 | [C(OP_READ)] = { | ||
875 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
876 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS, | ||
877 | }, | ||
878 | [C(OP_WRITE)] = { | ||
879 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
880 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS, | ||
881 | }, | ||
882 | [C(OP_PREFETCH)] = { | ||
883 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
884 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
885 | }, | ||
886 | }, | ||
887 | [C(ITLB)] = { | ||
888 | [C(OP_READ)] = { | ||
889 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
890 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS, | ||
891 | }, | ||
892 | [C(OP_WRITE)] = { | ||
893 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
894 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS, | ||
895 | }, | ||
896 | [C(OP_PREFETCH)] = { | ||
897 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
898 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
899 | }, | ||
900 | }, | ||
901 | [C(BPU)] = { | ||
902 | [C(OP_READ)] = { | ||
903 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
904 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
905 | }, | ||
906 | [C(OP_WRITE)] = { | ||
907 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
908 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
909 | }, | ||
910 | [C(OP_PREFETCH)] = { | ||
911 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
912 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
913 | }, | ||
914 | }, | ||
915 | }; | ||
916 | |||
917 | static inline unsigned long | ||
918 | armv6_pmcr_read(void) | ||
919 | { | ||
920 | u32 val; | ||
921 | asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val)); | ||
922 | return val; | ||
923 | } | ||
924 | |||
925 | static inline void | ||
926 | armv6_pmcr_write(unsigned long val) | ||
927 | { | ||
928 | asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val)); | ||
929 | } | ||
930 | |||
931 | #define ARMV6_PMCR_ENABLE (1 << 0) | ||
932 | #define ARMV6_PMCR_CTR01_RESET (1 << 1) | ||
933 | #define ARMV6_PMCR_CCOUNT_RESET (1 << 2) | ||
934 | #define ARMV6_PMCR_CCOUNT_DIV (1 << 3) | ||
935 | #define ARMV6_PMCR_COUNT0_IEN (1 << 4) | ||
936 | #define ARMV6_PMCR_COUNT1_IEN (1 << 5) | ||
937 | #define ARMV6_PMCR_CCOUNT_IEN (1 << 6) | ||
938 | #define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8) | ||
939 | #define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9) | ||
940 | #define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10) | ||
941 | #define ARMV6_PMCR_EVT_COUNT0_SHIFT 20 | ||
942 | #define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT) | ||
943 | #define ARMV6_PMCR_EVT_COUNT1_SHIFT 12 | ||
944 | #define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT) | ||
945 | |||
946 | #define ARMV6_PMCR_OVERFLOWED_MASK \ | ||
947 | (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \ | ||
948 | ARMV6_PMCR_CCOUNT_OVERFLOW) | ||
949 | |||
950 | static inline int | ||
951 | armv6_pmcr_has_overflowed(unsigned long pmcr) | ||
952 | { | ||
953 | return (pmcr & ARMV6_PMCR_OVERFLOWED_MASK); | ||
954 | } | ||
955 | |||
956 | static inline int | ||
957 | armv6_pmcr_counter_has_overflowed(unsigned long pmcr, | ||
958 | enum armv6_counters counter) | ||
959 | { | ||
960 | int ret = 0; | ||
961 | |||
962 | if (ARMV6_CYCLE_COUNTER == counter) | ||
963 | ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW; | ||
964 | else if (ARMV6_COUNTER0 == counter) | ||
965 | ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW; | ||
966 | else if (ARMV6_COUNTER1 == counter) | ||
967 | ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW; | ||
968 | else | ||
969 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
970 | |||
971 | return ret; | ||
972 | } | ||
973 | |||
974 | static inline u32 | ||
975 | armv6pmu_read_counter(int counter) | ||
976 | { | ||
977 | unsigned long value = 0; | ||
978 | |||
979 | if (ARMV6_CYCLE_COUNTER == counter) | ||
980 | asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value)); | ||
981 | else if (ARMV6_COUNTER0 == counter) | ||
982 | asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value)); | ||
983 | else if (ARMV6_COUNTER1 == counter) | ||
984 | asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value)); | ||
985 | else | ||
986 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
987 | |||
988 | return value; | ||
989 | } | ||
990 | |||
991 | static inline void | ||
992 | armv6pmu_write_counter(int counter, | ||
993 | u32 value) | ||
994 | { | ||
995 | if (ARMV6_CYCLE_COUNTER == counter) | ||
996 | asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value)); | ||
997 | else if (ARMV6_COUNTER0 == counter) | ||
998 | asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value)); | ||
999 | else if (ARMV6_COUNTER1 == counter) | ||
1000 | asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value)); | ||
1001 | else | ||
1002 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
1003 | } | ||
1004 | |||
1005 | void | ||
1006 | armv6pmu_enable_event(struct hw_perf_event *hwc, | ||
1007 | int idx) | ||
1008 | { | ||
1009 | unsigned long val, mask, evt, flags; | ||
1010 | |||
1011 | if (ARMV6_CYCLE_COUNTER == idx) { | ||
1012 | mask = 0; | ||
1013 | evt = ARMV6_PMCR_CCOUNT_IEN; | ||
1014 | } else if (ARMV6_COUNTER0 == idx) { | ||
1015 | mask = ARMV6_PMCR_EVT_COUNT0_MASK; | ||
1016 | evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) | | ||
1017 | ARMV6_PMCR_COUNT0_IEN; | ||
1018 | } else if (ARMV6_COUNTER1 == idx) { | ||
1019 | mask = ARMV6_PMCR_EVT_COUNT1_MASK; | ||
1020 | evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) | | ||
1021 | ARMV6_PMCR_COUNT1_IEN; | ||
1022 | } else { | ||
1023 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
1024 | return; | ||
1025 | } | ||
1026 | |||
1027 | /* | ||
1028 | * Mask out the current event and set the counter to count the event | ||
1029 | * that we're interested in. | ||
1030 | */ | ||
1031 | spin_lock_irqsave(&pmu_lock, flags); | ||
1032 | val = armv6_pmcr_read(); | ||
1033 | val &= ~mask; | ||
1034 | val |= evt; | ||
1035 | armv6_pmcr_write(val); | ||
1036 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1037 | } | ||
1038 | |||
1039 | static irqreturn_t | ||
1040 | armv6pmu_handle_irq(int irq_num, | ||
1041 | void *dev) | ||
1042 | { | ||
1043 | unsigned long pmcr = armv6_pmcr_read(); | ||
1044 | struct perf_sample_data data; | ||
1045 | struct cpu_hw_events *cpuc; | ||
1046 | struct pt_regs *regs; | ||
1047 | int idx; | ||
1048 | |||
1049 | if (!armv6_pmcr_has_overflowed(pmcr)) | ||
1050 | return IRQ_NONE; | ||
1051 | |||
1052 | regs = get_irq_regs(); | ||
1053 | |||
1054 | /* | ||
1055 | * The interrupts are cleared by writing the overflow flags back to | ||
1056 | * the control register. All of the other bits don't have any effect | ||
1057 | * if they are rewritten, so write the whole value back. | ||
1058 | */ | ||
1059 | armv6_pmcr_write(pmcr); | ||
1060 | |||
1061 | perf_sample_data_init(&data, 0); | ||
1062 | |||
1063 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
1064 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
1065 | struct perf_event *event = cpuc->events[idx]; | ||
1066 | struct hw_perf_event *hwc; | ||
1067 | |||
1068 | if (!test_bit(idx, cpuc->active_mask)) | ||
1069 | continue; | ||
1070 | |||
1071 | /* | ||
1072 | * We have a single interrupt for all counters. Check that | ||
1073 | * each counter has overflowed before we process it. | ||
1074 | */ | ||
1075 | if (!armv6_pmcr_counter_has_overflowed(pmcr, idx)) | ||
1076 | continue; | ||
1077 | |||
1078 | hwc = &event->hw; | ||
1079 | armpmu_event_update(event, hwc, idx); | ||
1080 | data.period = event->hw.last_period; | ||
1081 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
1082 | continue; | ||
1083 | |||
1084 | if (perf_event_overflow(event, 0, &data, regs)) | ||
1085 | armpmu->disable(hwc, idx); | ||
1086 | } | ||
1087 | |||
1088 | /* | ||
1089 | * Handle the pending perf events. | ||
1090 | * | ||
1091 | * Note: this call *must* be run with interrupts disabled. For | ||
1092 | * platforms that can have the PMU interrupts raised as an NMI, this | ||
1093 | * will not work. | ||
1094 | */ | ||
1095 | irq_work_run(); | ||
1096 | |||
1097 | return IRQ_HANDLED; | ||
1098 | } | ||
1099 | |||
1100 | static void | ||
1101 | armv6pmu_start(void) | ||
1102 | { | ||
1103 | unsigned long flags, val; | ||
1104 | |||
1105 | spin_lock_irqsave(&pmu_lock, flags); | ||
1106 | val = armv6_pmcr_read(); | ||
1107 | val |= ARMV6_PMCR_ENABLE; | ||
1108 | armv6_pmcr_write(val); | ||
1109 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1110 | } | ||
1111 | |||
1112 | void | ||
1113 | armv6pmu_stop(void) | ||
1114 | { | ||
1115 | unsigned long flags, val; | ||
1116 | |||
1117 | spin_lock_irqsave(&pmu_lock, flags); | ||
1118 | val = armv6_pmcr_read(); | ||
1119 | val &= ~ARMV6_PMCR_ENABLE; | ||
1120 | armv6_pmcr_write(val); | ||
1121 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1122 | } | ||
1123 | |||
1124 | static inline int | ||
1125 | armv6pmu_event_map(int config) | ||
1126 | { | ||
1127 | int mapping = armv6_perf_map[config]; | ||
1128 | if (HW_OP_UNSUPPORTED == mapping) | ||
1129 | mapping = -EOPNOTSUPP; | ||
1130 | return mapping; | ||
1131 | } | ||
1132 | |||
1133 | static inline int | ||
1134 | armv6mpcore_pmu_event_map(int config) | ||
1135 | { | ||
1136 | int mapping = armv6mpcore_perf_map[config]; | ||
1137 | if (HW_OP_UNSUPPORTED == mapping) | ||
1138 | mapping = -EOPNOTSUPP; | ||
1139 | return mapping; | ||
1140 | } | ||
1141 | |||
1142 | static u64 | ||
1143 | armv6pmu_raw_event(u64 config) | ||
1144 | { | ||
1145 | return config & 0xff; | ||
1146 | } | ||
1147 | |||
1148 | static int | ||
1149 | armv6pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
1150 | struct hw_perf_event *event) | ||
1151 | { | ||
1152 | /* Always place a cycle counter into the cycle counter. */ | ||
1153 | if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) { | ||
1154 | if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask)) | ||
1155 | return -EAGAIN; | ||
1156 | |||
1157 | return ARMV6_CYCLE_COUNTER; | ||
1158 | } else { | ||
1159 | /* | ||
1160 | * For anything other than a cycle counter, try and use | ||
1161 | * counter0 and counter1. | ||
1162 | */ | ||
1163 | if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask)) { | ||
1164 | return ARMV6_COUNTER1; | ||
1165 | } | ||
1166 | |||
1167 | if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask)) { | ||
1168 | return ARMV6_COUNTER0; | ||
1169 | } | ||
1170 | |||
1171 | /* The counters are all in use. */ | ||
1172 | return -EAGAIN; | ||
1173 | } | ||
1174 | } | ||
1175 | |||
1176 | static void | ||
1177 | armv6pmu_disable_event(struct hw_perf_event *hwc, | ||
1178 | int idx) | ||
1179 | { | ||
1180 | unsigned long val, mask, evt, flags; | ||
1181 | |||
1182 | if (ARMV6_CYCLE_COUNTER == idx) { | ||
1183 | mask = ARMV6_PMCR_CCOUNT_IEN; | ||
1184 | evt = 0; | ||
1185 | } else if (ARMV6_COUNTER0 == idx) { | ||
1186 | mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK; | ||
1187 | evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT; | ||
1188 | } else if (ARMV6_COUNTER1 == idx) { | ||
1189 | mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK; | ||
1190 | evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT; | ||
1191 | } else { | ||
1192 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
1193 | return; | ||
1194 | } | ||
1195 | |||
1196 | /* | ||
1197 | * Mask out the current event and set the counter to count the number | ||
1198 | * of ETM bus signal assertion cycles. The external reporting should | ||
1199 | * be disabled and so this should never increment. | ||
1200 | */ | ||
1201 | spin_lock_irqsave(&pmu_lock, flags); | ||
1202 | val = armv6_pmcr_read(); | ||
1203 | val &= ~mask; | ||
1204 | val |= evt; | ||
1205 | armv6_pmcr_write(val); | ||
1206 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1207 | } | ||
1208 | |||
1209 | static void | ||
1210 | armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, | ||
1211 | int idx) | ||
1212 | { | ||
1213 | unsigned long val, mask, flags, evt = 0; | ||
1214 | |||
1215 | if (ARMV6_CYCLE_COUNTER == idx) { | ||
1216 | mask = ARMV6_PMCR_CCOUNT_IEN; | ||
1217 | } else if (ARMV6_COUNTER0 == idx) { | ||
1218 | mask = ARMV6_PMCR_COUNT0_IEN; | ||
1219 | } else if (ARMV6_COUNTER1 == idx) { | ||
1220 | mask = ARMV6_PMCR_COUNT1_IEN; | ||
1221 | } else { | ||
1222 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
1223 | return; | ||
1224 | } | ||
1225 | |||
1226 | /* | ||
1227 | * Unlike UP ARMv6, we don't have a way of stopping the counters. We | ||
1228 | * simply disable the interrupt reporting. | ||
1229 | */ | ||
1230 | spin_lock_irqsave(&pmu_lock, flags); | ||
1231 | val = armv6_pmcr_read(); | ||
1232 | val &= ~mask; | ||
1233 | val |= evt; | ||
1234 | armv6_pmcr_write(val); | ||
1235 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1236 | } | ||
1237 | |||
1238 | static const struct arm_pmu armv6pmu = { | ||
1239 | .id = ARM_PERF_PMU_ID_V6, | ||
1240 | .handle_irq = armv6pmu_handle_irq, | ||
1241 | .enable = armv6pmu_enable_event, | ||
1242 | .disable = armv6pmu_disable_event, | ||
1243 | .event_map = armv6pmu_event_map, | ||
1244 | .raw_event = armv6pmu_raw_event, | ||
1245 | .read_counter = armv6pmu_read_counter, | ||
1246 | .write_counter = armv6pmu_write_counter, | ||
1247 | .get_event_idx = armv6pmu_get_event_idx, | ||
1248 | .start = armv6pmu_start, | ||
1249 | .stop = armv6pmu_stop, | ||
1250 | .num_events = 3, | ||
1251 | .max_period = (1LLU << 32) - 1, | ||
1252 | }; | ||
1253 | |||
1254 | /* | ||
1255 | * ARMv6mpcore is almost identical to single core ARMv6 with the exception | ||
1256 | * that some of the events have different enumerations and that there is no | ||
1257 | * *hack* to stop the programmable counters. To stop the counters we simply | ||
1258 | * disable the interrupt reporting and update the event. When unthrottling we | ||
1259 | * reset the period and enable the interrupt reporting. | ||
1260 | */ | ||
1261 | static const struct arm_pmu armv6mpcore_pmu = { | ||
1262 | .id = ARM_PERF_PMU_ID_V6MP, | ||
1263 | .handle_irq = armv6pmu_handle_irq, | ||
1264 | .enable = armv6pmu_enable_event, | ||
1265 | .disable = armv6mpcore_pmu_disable_event, | ||
1266 | .event_map = armv6mpcore_pmu_event_map, | ||
1267 | .raw_event = armv6pmu_raw_event, | ||
1268 | .read_counter = armv6pmu_read_counter, | ||
1269 | .write_counter = armv6pmu_write_counter, | ||
1270 | .get_event_idx = armv6pmu_get_event_idx, | ||
1271 | .start = armv6pmu_start, | ||
1272 | .stop = armv6pmu_stop, | ||
1273 | .num_events = 3, | ||
1274 | .max_period = (1LLU << 32) - 1, | ||
1275 | }; | ||
1276 | |||
1277 | /* | ||
1278 | * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code. | ||
1279 | * | ||
1280 | * Copied from ARMv6 code, with the low level code inspired | ||
1281 | * by the ARMv7 Oprofile code. | ||
1282 | * | ||
1283 | * Cortex-A8 has up to 4 configurable performance counters and | ||
1284 | * a single cycle counter. | ||
1285 | * Cortex-A9 has up to 31 configurable performance counters and | ||
1286 | * a single cycle counter. | ||
1287 | * | ||
1288 | * All counters can be enabled/disabled and IRQ masked separately. The cycle | ||
1289 | * counter and all 4 performance counters together can be reset separately. | ||
1290 | */ | ||
1291 | |||
1292 | /* Common ARMv7 event types */ | ||
1293 | enum armv7_perf_types { | ||
1294 | ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, | ||
1295 | ARMV7_PERFCTR_IFETCH_MISS = 0x01, | ||
1296 | ARMV7_PERFCTR_ITLB_MISS = 0x02, | ||
1297 | ARMV7_PERFCTR_DCACHE_REFILL = 0x03, | ||
1298 | ARMV7_PERFCTR_DCACHE_ACCESS = 0x04, | ||
1299 | ARMV7_PERFCTR_DTLB_REFILL = 0x05, | ||
1300 | ARMV7_PERFCTR_DREAD = 0x06, | ||
1301 | ARMV7_PERFCTR_DWRITE = 0x07, | ||
1302 | |||
1303 | ARMV7_PERFCTR_EXC_TAKEN = 0x09, | ||
1304 | ARMV7_PERFCTR_EXC_EXECUTED = 0x0A, | ||
1305 | ARMV7_PERFCTR_CID_WRITE = 0x0B, | ||
1306 | /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS. | ||
1307 | * It counts: | ||
1308 | * - all branch instructions, | ||
1309 | * - instructions that explicitly write the PC, | ||
1310 | * - exception generating instructions. | ||
1311 | */ | ||
1312 | ARMV7_PERFCTR_PC_WRITE = 0x0C, | ||
1313 | ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D, | ||
1314 | ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F, | ||
1315 | ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10, | ||
1316 | ARMV7_PERFCTR_CLOCK_CYCLES = 0x11, | ||
1317 | |||
1318 | ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12, | ||
1319 | |||
1320 | ARMV7_PERFCTR_CPU_CYCLES = 0xFF | ||
1321 | }; | ||
1322 | |||
1323 | /* ARMv7 Cortex-A8 specific event types */ | ||
1324 | enum armv7_a8_perf_types { | ||
1325 | ARMV7_PERFCTR_INSTR_EXECUTED = 0x08, | ||
1326 | |||
1327 | ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E, | ||
1328 | |||
1329 | ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40, | ||
1330 | ARMV7_PERFCTR_L2_STORE_MERGED = 0x41, | ||
1331 | ARMV7_PERFCTR_L2_STORE_BUFF = 0x42, | ||
1332 | ARMV7_PERFCTR_L2_ACCESS = 0x43, | ||
1333 | ARMV7_PERFCTR_L2_CACH_MISS = 0x44, | ||
1334 | ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45, | ||
1335 | ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46, | ||
1336 | ARMV7_PERFCTR_MEMORY_REPLAY = 0x47, | ||
1337 | ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48, | ||
1338 | ARMV7_PERFCTR_L1_DATA_MISS = 0x49, | ||
1339 | ARMV7_PERFCTR_L1_INST_MISS = 0x4A, | ||
1340 | ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B, | ||
1341 | ARMV7_PERFCTR_L1_NEON_DATA = 0x4C, | ||
1342 | ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D, | ||
1343 | ARMV7_PERFCTR_L2_NEON = 0x4E, | ||
1344 | ARMV7_PERFCTR_L2_NEON_HIT = 0x4F, | ||
1345 | ARMV7_PERFCTR_L1_INST = 0x50, | ||
1346 | ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51, | ||
1347 | ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52, | ||
1348 | ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53, | ||
1349 | ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54, | ||
1350 | ARMV7_PERFCTR_OP_EXECUTED = 0x55, | ||
1351 | ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56, | ||
1352 | ARMV7_PERFCTR_CYCLES_INST = 0x57, | ||
1353 | ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58, | ||
1354 | ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59, | ||
1355 | ARMV7_PERFCTR_NEON_CYCLES = 0x5A, | ||
1356 | |||
1357 | ARMV7_PERFCTR_PMU0_EVENTS = 0x70, | ||
1358 | ARMV7_PERFCTR_PMU1_EVENTS = 0x71, | ||
1359 | ARMV7_PERFCTR_PMU_EVENTS = 0x72, | ||
1360 | }; | ||
1361 | |||
1362 | /* ARMv7 Cortex-A9 specific event types */ | ||
1363 | enum armv7_a9_perf_types { | ||
1364 | ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40, | ||
1365 | ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41, | ||
1366 | ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42, | ||
1367 | |||
1368 | ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50, | ||
1369 | ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51, | ||
1370 | |||
1371 | ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60, | ||
1372 | ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61, | ||
1373 | ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62, | ||
1374 | ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63, | ||
1375 | ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64, | ||
1376 | ARMV7_PERFCTR_DATA_EVICTION = 0x65, | ||
1377 | ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66, | ||
1378 | ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67, | ||
1379 | ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68, | ||
1380 | |||
1381 | ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E, | ||
1382 | |||
1383 | ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70, | ||
1384 | ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71, | ||
1385 | ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72, | ||
1386 | ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73, | ||
1387 | ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74, | ||
1388 | |||
1389 | ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80, | ||
1390 | ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81, | ||
1391 | ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82, | ||
1392 | ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83, | ||
1393 | ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84, | ||
1394 | ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85, | ||
1395 | ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86, | ||
1396 | |||
1397 | ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A, | ||
1398 | ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B, | ||
1399 | |||
1400 | ARMV7_PERFCTR_ISB_INST = 0x90, | ||
1401 | ARMV7_PERFCTR_DSB_INST = 0x91, | ||
1402 | ARMV7_PERFCTR_DMB_INST = 0x92, | ||
1403 | ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93, | ||
1404 | |||
1405 | ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0, | ||
1406 | ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1, | ||
1407 | ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2, | ||
1408 | ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3, | ||
1409 | ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4, | ||
1410 | ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5 | ||
1411 | }; | ||
1412 | |||
1413 | /* | ||
1414 | * Cortex-A8 HW events mapping | ||
1415 | * | ||
1416 | * The hardware events that we support. We do support cache operations but | ||
1417 | * we have harvard caches and no way to combine instruction and data | ||
1418 | * accesses/misses in hardware. | ||
1419 | */ | ||
1420 | static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = { | ||
1421 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, | ||
1422 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, | ||
1423 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
1424 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
1425 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, | ||
1426 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
1427 | [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, | ||
1428 | }; | ||
1429 | |||
1430 | static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
1431 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
1432 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
1433 | [C(L1D)] = { | ||
1434 | /* | ||
1435 | * The performance counters don't differentiate between read | ||
1436 | * and write accesses/misses so this isn't strictly correct, | ||
1437 | * but it's the best we can do. Writes and reads get | ||
1438 | * combined. | ||
1439 | */ | ||
1440 | [C(OP_READ)] = { | ||
1441 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
1442 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
1443 | }, | ||
1444 | [C(OP_WRITE)] = { | ||
1445 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
1446 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
1447 | }, | ||
1448 | [C(OP_PREFETCH)] = { | ||
1449 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1450 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1451 | }, | ||
1452 | }, | ||
1453 | [C(L1I)] = { | ||
1454 | [C(OP_READ)] = { | ||
1455 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, | ||
1456 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, | ||
1457 | }, | ||
1458 | [C(OP_WRITE)] = { | ||
1459 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, | ||
1460 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, | ||
1461 | }, | ||
1462 | [C(OP_PREFETCH)] = { | ||
1463 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1464 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1465 | }, | ||
1466 | }, | ||
1467 | [C(LL)] = { | ||
1468 | [C(OP_READ)] = { | ||
1469 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, | ||
1470 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, | ||
1471 | }, | ||
1472 | [C(OP_WRITE)] = { | ||
1473 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, | ||
1474 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, | ||
1475 | }, | ||
1476 | [C(OP_PREFETCH)] = { | ||
1477 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1478 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1479 | }, | ||
1480 | }, | ||
1481 | [C(DTLB)] = { | ||
1482 | /* | ||
1483 | * Only ITLB misses and DTLB refills are supported. | ||
1484 | * If users want the DTLB refills misses a raw counter | ||
1485 | * must be used. | ||
1486 | */ | ||
1487 | [C(OP_READ)] = { | ||
1488 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1489 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
1490 | }, | ||
1491 | [C(OP_WRITE)] = { | ||
1492 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1493 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
1494 | }, | ||
1495 | [C(OP_PREFETCH)] = { | ||
1496 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1497 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1498 | }, | ||
1499 | }, | ||
1500 | [C(ITLB)] = { | ||
1501 | [C(OP_READ)] = { | ||
1502 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1503 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
1504 | }, | ||
1505 | [C(OP_WRITE)] = { | ||
1506 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1507 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
1508 | }, | ||
1509 | [C(OP_PREFETCH)] = { | ||
1510 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1511 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1512 | }, | ||
1513 | }, | ||
1514 | [C(BPU)] = { | ||
1515 | [C(OP_READ)] = { | ||
1516 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
1517 | [C(RESULT_MISS)] | ||
1518 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
1519 | }, | ||
1520 | [C(OP_WRITE)] = { | ||
1521 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
1522 | [C(RESULT_MISS)] | ||
1523 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
1524 | }, | ||
1525 | [C(OP_PREFETCH)] = { | ||
1526 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1527 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1528 | }, | ||
1529 | }, | ||
1530 | }; | ||
1531 | |||
1532 | /* | ||
1533 | * Cortex-A9 HW events mapping | ||
1534 | */ | ||
1535 | static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = { | ||
1536 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, | ||
1537 | [PERF_COUNT_HW_INSTRUCTIONS] = | ||
1538 | ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE, | ||
1539 | [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT, | ||
1540 | [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS, | ||
1541 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, | ||
1542 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
1543 | [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, | ||
1544 | }; | ||
1545 | |||
1546 | static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
1547 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
1548 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
1549 | [C(L1D)] = { | ||
1550 | /* | ||
1551 | * The performance counters don't differentiate between read | ||
1552 | * and write accesses/misses so this isn't strictly correct, | ||
1553 | * but it's the best we can do. Writes and reads get | ||
1554 | * combined. | ||
1555 | */ | ||
1556 | [C(OP_READ)] = { | ||
1557 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
1558 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
1559 | }, | ||
1560 | [C(OP_WRITE)] = { | ||
1561 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
1562 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
1563 | }, | ||
1564 | [C(OP_PREFETCH)] = { | ||
1565 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1566 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1567 | }, | ||
1568 | }, | ||
1569 | [C(L1I)] = { | ||
1570 | [C(OP_READ)] = { | ||
1571 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1572 | [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, | ||
1573 | }, | ||
1574 | [C(OP_WRITE)] = { | ||
1575 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1576 | [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, | ||
1577 | }, | ||
1578 | [C(OP_PREFETCH)] = { | ||
1579 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1580 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1581 | }, | ||
1582 | }, | ||
1583 | [C(LL)] = { | ||
1584 | [C(OP_READ)] = { | ||
1585 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1586 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1587 | }, | ||
1588 | [C(OP_WRITE)] = { | ||
1589 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1590 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1591 | }, | ||
1592 | [C(OP_PREFETCH)] = { | ||
1593 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1594 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1595 | }, | ||
1596 | }, | ||
1597 | [C(DTLB)] = { | ||
1598 | /* | ||
1599 | * Only ITLB misses and DTLB refills are supported. | ||
1600 | * If users want the DTLB refills misses a raw counter | ||
1601 | * must be used. | ||
1602 | */ | ||
1603 | [C(OP_READ)] = { | ||
1604 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1605 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
1606 | }, | ||
1607 | [C(OP_WRITE)] = { | ||
1608 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1609 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
1610 | }, | ||
1611 | [C(OP_PREFETCH)] = { | ||
1612 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1613 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1614 | }, | ||
1615 | }, | ||
1616 | [C(ITLB)] = { | ||
1617 | [C(OP_READ)] = { | ||
1618 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1619 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
1620 | }, | ||
1621 | [C(OP_WRITE)] = { | ||
1622 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1623 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
1624 | }, | ||
1625 | [C(OP_PREFETCH)] = { | ||
1626 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1627 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1628 | }, | ||
1629 | }, | ||
1630 | [C(BPU)] = { | ||
1631 | [C(OP_READ)] = { | ||
1632 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
1633 | [C(RESULT_MISS)] | ||
1634 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
1635 | }, | ||
1636 | [C(OP_WRITE)] = { | ||
1637 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
1638 | [C(RESULT_MISS)] | ||
1639 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
1640 | }, | ||
1641 | [C(OP_PREFETCH)] = { | ||
1642 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
1643 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
1644 | }, | ||
1645 | }, | ||
1646 | }; | ||
1647 | |||
1648 | /* | ||
1649 | * Perf Events counters | ||
1650 | */ | ||
1651 | enum armv7_counters { | ||
1652 | ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */ | ||
1653 | ARMV7_COUNTER0 = 2, /* First event counter */ | ||
1654 | }; | ||
1655 | |||
1656 | /* | ||
1657 | * The cycle counter is ARMV7_CYCLE_COUNTER. | ||
1658 | * The first event counter is ARMV7_COUNTER0. | ||
1659 | * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1). | ||
1660 | */ | ||
1661 | #define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1) | ||
1662 | |||
1663 | /* | ||
1664 | * ARMv7 low level PMNC access | ||
1665 | */ | ||
1666 | |||
1667 | /* | ||
1668 | * Per-CPU PMNC: config reg | ||
1669 | */ | ||
1670 | #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */ | ||
1671 | #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */ | ||
1672 | #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */ | ||
1673 | #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */ | ||
1674 | #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */ | ||
1675 | #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ | ||
1676 | #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */ | ||
1677 | #define ARMV7_PMNC_N_MASK 0x1f | ||
1678 | #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */ | ||
1679 | |||
1680 | /* | ||
1681 | * Available counters | ||
1682 | */ | ||
1683 | #define ARMV7_CNT0 0 /* First event counter */ | ||
1684 | #define ARMV7_CCNT 31 /* Cycle counter */ | ||
1685 | |||
1686 | /* Perf Event to low level counters mapping */ | ||
1687 | #define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0) | ||
1688 | |||
1689 | /* | ||
1690 | * CNTENS: counters enable reg | ||
1691 | */ | ||
1692 | #define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
1693 | #define ARMV7_CNTENS_C (1 << ARMV7_CCNT) | ||
1694 | |||
1695 | /* | ||
1696 | * CNTENC: counters disable reg | ||
1697 | */ | ||
1698 | #define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
1699 | #define ARMV7_CNTENC_C (1 << ARMV7_CCNT) | ||
1700 | |||
1701 | /* | ||
1702 | * INTENS: counters overflow interrupt enable reg | ||
1703 | */ | ||
1704 | #define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
1705 | #define ARMV7_INTENS_C (1 << ARMV7_CCNT) | ||
1706 | |||
1707 | /* | ||
1708 | * INTENC: counters overflow interrupt disable reg | ||
1709 | */ | ||
1710 | #define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
1711 | #define ARMV7_INTENC_C (1 << ARMV7_CCNT) | ||
1712 | |||
1713 | /* | ||
1714 | * EVTSEL: Event selection reg | ||
1715 | */ | ||
1716 | #define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */ | ||
1717 | |||
1718 | /* | ||
1719 | * SELECT: Counter selection reg | ||
1720 | */ | ||
1721 | #define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */ | ||
1722 | |||
1723 | /* | ||
1724 | * FLAG: counters overflow flag status reg | ||
1725 | */ | ||
1726 | #define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
1727 | #define ARMV7_FLAG_C (1 << ARMV7_CCNT) | ||
1728 | #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */ | ||
1729 | #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK | ||
1730 | |||
1731 | static inline unsigned long armv7_pmnc_read(void) | ||
1732 | { | ||
1733 | u32 val; | ||
1734 | asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val)); | ||
1735 | return val; | ||
1736 | } | ||
1737 | |||
1738 | static inline void armv7_pmnc_write(unsigned long val) | ||
1739 | { | ||
1740 | val &= ARMV7_PMNC_MASK; | ||
1741 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); | ||
1742 | } | ||
1743 | |||
1744 | static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) | ||
1745 | { | ||
1746 | return pmnc & ARMV7_OVERFLOWED_MASK; | ||
1747 | } | ||
1748 | |||
1749 | static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, | ||
1750 | enum armv7_counters counter) | ||
1751 | { | ||
1752 | int ret = 0; | ||
1753 | |||
1754 | if (counter == ARMV7_CYCLE_COUNTER) | ||
1755 | ret = pmnc & ARMV7_FLAG_C; | ||
1756 | else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST)) | ||
1757 | ret = pmnc & ARMV7_FLAG_P(counter); | ||
1758 | else | ||
1759 | pr_err("CPU%u checking wrong counter %d overflow status\n", | ||
1760 | smp_processor_id(), counter); | ||
1761 | |||
1762 | return ret; | ||
1763 | } | ||
1764 | |||
1765 | static inline int armv7_pmnc_select_counter(unsigned int idx) | ||
1766 | { | ||
1767 | u32 val; | ||
1768 | |||
1769 | if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) { | ||
1770 | pr_err("CPU%u selecting wrong PMNC counter" | ||
1771 | " %d\n", smp_processor_id(), idx); | ||
1772 | return -1; | ||
1773 | } | ||
1774 | |||
1775 | val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; | ||
1776 | asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); | ||
1777 | |||
1778 | return idx; | ||
1779 | } | ||
1780 | |||
1781 | static inline u32 armv7pmu_read_counter(int idx) | ||
1782 | { | ||
1783 | unsigned long value = 0; | ||
1784 | |||
1785 | if (idx == ARMV7_CYCLE_COUNTER) | ||
1786 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); | ||
1787 | else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { | ||
1788 | if (armv7_pmnc_select_counter(idx) == idx) | ||
1789 | asm volatile("mrc p15, 0, %0, c9, c13, 2" | ||
1790 | : "=r" (value)); | ||
1791 | } else | ||
1792 | pr_err("CPU%u reading wrong counter %d\n", | ||
1793 | smp_processor_id(), idx); | ||
1794 | |||
1795 | return value; | ||
1796 | } | ||
1797 | |||
1798 | static inline void armv7pmu_write_counter(int idx, u32 value) | ||
1799 | { | ||
1800 | if (idx == ARMV7_CYCLE_COUNTER) | ||
1801 | asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); | ||
1802 | else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { | ||
1803 | if (armv7_pmnc_select_counter(idx) == idx) | ||
1804 | asm volatile("mcr p15, 0, %0, c9, c13, 2" | ||
1805 | : : "r" (value)); | ||
1806 | } else | ||
1807 | pr_err("CPU%u writing wrong counter %d\n", | ||
1808 | smp_processor_id(), idx); | ||
1809 | } | ||
1810 | |||
1811 | static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val) | ||
1812 | { | ||
1813 | if (armv7_pmnc_select_counter(idx) == idx) { | ||
1814 | val &= ARMV7_EVTSEL_MASK; | ||
1815 | asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); | ||
1816 | } | ||
1817 | } | ||
1818 | |||
1819 | static inline u32 armv7_pmnc_enable_counter(unsigned int idx) | ||
1820 | { | ||
1821 | u32 val; | ||
1822 | |||
1823 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
1824 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
1825 | pr_err("CPU%u enabling wrong PMNC counter" | ||
1826 | " %d\n", smp_processor_id(), idx); | ||
1827 | return -1; | ||
1828 | } | ||
1829 | |||
1830 | if (idx == ARMV7_CYCLE_COUNTER) | ||
1831 | val = ARMV7_CNTENS_C; | ||
1832 | else | ||
1833 | val = ARMV7_CNTENS_P(idx); | ||
1834 | |||
1835 | asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); | ||
1836 | |||
1837 | return idx; | ||
1838 | } | ||
1839 | |||
1840 | static inline u32 armv7_pmnc_disable_counter(unsigned int idx) | ||
1841 | { | ||
1842 | u32 val; | ||
1843 | |||
1844 | |||
1845 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
1846 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
1847 | pr_err("CPU%u disabling wrong PMNC counter" | ||
1848 | " %d\n", smp_processor_id(), idx); | ||
1849 | return -1; | ||
1850 | } | ||
1851 | |||
1852 | if (idx == ARMV7_CYCLE_COUNTER) | ||
1853 | val = ARMV7_CNTENC_C; | ||
1854 | else | ||
1855 | val = ARMV7_CNTENC_P(idx); | ||
1856 | |||
1857 | asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); | ||
1858 | |||
1859 | return idx; | ||
1860 | } | ||
1861 | |||
1862 | static inline u32 armv7_pmnc_enable_intens(unsigned int idx) | ||
1863 | { | ||
1864 | u32 val; | ||
1865 | |||
1866 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
1867 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
1868 | pr_err("CPU%u enabling wrong PMNC counter" | ||
1869 | " interrupt enable %d\n", smp_processor_id(), idx); | ||
1870 | return -1; | ||
1871 | } | ||
1872 | |||
1873 | if (idx == ARMV7_CYCLE_COUNTER) | ||
1874 | val = ARMV7_INTENS_C; | ||
1875 | else | ||
1876 | val = ARMV7_INTENS_P(idx); | ||
1877 | |||
1878 | asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val)); | ||
1879 | |||
1880 | return idx; | ||
1881 | } | ||
1882 | |||
1883 | static inline u32 armv7_pmnc_disable_intens(unsigned int idx) | ||
1884 | { | ||
1885 | u32 val; | ||
1886 | |||
1887 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
1888 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
1889 | pr_err("CPU%u disabling wrong PMNC counter" | ||
1890 | " interrupt enable %d\n", smp_processor_id(), idx); | ||
1891 | return -1; | ||
1892 | } | ||
1893 | |||
1894 | if (idx == ARMV7_CYCLE_COUNTER) | ||
1895 | val = ARMV7_INTENC_C; | ||
1896 | else | ||
1897 | val = ARMV7_INTENC_P(idx); | ||
1898 | |||
1899 | asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val)); | ||
1900 | |||
1901 | return idx; | ||
1902 | } | ||
1903 | |||
1904 | static inline u32 armv7_pmnc_getreset_flags(void) | ||
1905 | { | ||
1906 | u32 val; | ||
1907 | |||
1908 | /* Read */ | ||
1909 | asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); | ||
1910 | |||
1911 | /* Write to clear flags */ | ||
1912 | val &= ARMV7_FLAG_MASK; | ||
1913 | asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val)); | ||
1914 | |||
1915 | return val; | ||
1916 | } | ||
1917 | |||
1918 | #ifdef DEBUG | ||
1919 | static void armv7_pmnc_dump_regs(void) | ||
1920 | { | ||
1921 | u32 val; | ||
1922 | unsigned int cnt; | ||
1923 | |||
1924 | printk(KERN_INFO "PMNC registers dump:\n"); | ||
1925 | |||
1926 | asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); | ||
1927 | printk(KERN_INFO "PMNC =0x%08x\n", val); | ||
1928 | |||
1929 | asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val)); | ||
1930 | printk(KERN_INFO "CNTENS=0x%08x\n", val); | ||
1931 | |||
1932 | asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val)); | ||
1933 | printk(KERN_INFO "INTENS=0x%08x\n", val); | ||
1934 | |||
1935 | asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); | ||
1936 | printk(KERN_INFO "FLAGS =0x%08x\n", val); | ||
1937 | |||
1938 | asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val)); | ||
1939 | printk(KERN_INFO "SELECT=0x%08x\n", val); | ||
1940 | |||
1941 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); | ||
1942 | printk(KERN_INFO "CCNT =0x%08x\n", val); | ||
1943 | |||
1944 | for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) { | ||
1945 | armv7_pmnc_select_counter(cnt); | ||
1946 | asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); | ||
1947 | printk(KERN_INFO "CNT[%d] count =0x%08x\n", | ||
1948 | cnt-ARMV7_EVENT_CNT_TO_CNTx, val); | ||
1949 | asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); | ||
1950 | printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", | ||
1951 | cnt-ARMV7_EVENT_CNT_TO_CNTx, val); | ||
1952 | } | ||
1953 | } | ||
1954 | #endif | ||
1955 | |||
1956 | void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | ||
1957 | { | ||
1958 | unsigned long flags; | ||
1959 | |||
1960 | /* | ||
1961 | * Enable counter and interrupt, and set the counter to count | ||
1962 | * the event that we're interested in. | ||
1963 | */ | ||
1964 | spin_lock_irqsave(&pmu_lock, flags); | ||
1965 | |||
1966 | /* | ||
1967 | * Disable counter | ||
1968 | */ | ||
1969 | armv7_pmnc_disable_counter(idx); | ||
1970 | |||
1971 | /* | ||
1972 | * Set event (if destined for PMNx counters) | ||
1973 | * We don't need to set the event if it's a cycle count | ||
1974 | */ | ||
1975 | if (idx != ARMV7_CYCLE_COUNTER) | ||
1976 | armv7_pmnc_write_evtsel(idx, hwc->config_base); | ||
1977 | |||
1978 | /* | ||
1979 | * Enable interrupt for this counter | ||
1980 | */ | ||
1981 | armv7_pmnc_enable_intens(idx); | ||
1982 | |||
1983 | /* | ||
1984 | * Enable counter | ||
1985 | */ | ||
1986 | armv7_pmnc_enable_counter(idx); | ||
1987 | |||
1988 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
1989 | } | ||
1990 | |||
1991 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | ||
1992 | { | ||
1993 | unsigned long flags; | ||
1994 | |||
1995 | /* | ||
1996 | * Disable counter and interrupt | ||
1997 | */ | ||
1998 | spin_lock_irqsave(&pmu_lock, flags); | ||
1999 | |||
2000 | /* | ||
2001 | * Disable counter | ||
2002 | */ | ||
2003 | armv7_pmnc_disable_counter(idx); | ||
2004 | |||
2005 | /* | ||
2006 | * Disable interrupt for this counter | ||
2007 | */ | ||
2008 | armv7_pmnc_disable_intens(idx); | ||
2009 | |||
2010 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2011 | } | ||
2012 | |||
2013 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | ||
2014 | { | ||
2015 | unsigned long pmnc; | ||
2016 | struct perf_sample_data data; | ||
2017 | struct cpu_hw_events *cpuc; | ||
2018 | struct pt_regs *regs; | ||
2019 | int idx; | ||
2020 | |||
2021 | /* | ||
2022 | * Get and reset the IRQ flags | ||
2023 | */ | ||
2024 | pmnc = armv7_pmnc_getreset_flags(); | ||
2025 | |||
2026 | /* | ||
2027 | * Did an overflow occur? | ||
2028 | */ | ||
2029 | if (!armv7_pmnc_has_overflowed(pmnc)) | ||
2030 | return IRQ_NONE; | ||
2031 | |||
2032 | /* | ||
2033 | * Handle the counter(s) overflow(s) | ||
2034 | */ | ||
2035 | regs = get_irq_regs(); | ||
2036 | |||
2037 | perf_sample_data_init(&data, 0); | ||
2038 | |||
2039 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
2040 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
2041 | struct perf_event *event = cpuc->events[idx]; | ||
2042 | struct hw_perf_event *hwc; | ||
2043 | |||
2044 | if (!test_bit(idx, cpuc->active_mask)) | ||
2045 | continue; | ||
2046 | |||
2047 | /* | ||
2048 | * We have a single interrupt for all counters. Check that | ||
2049 | * each counter has overflowed before we process it. | ||
2050 | */ | ||
2051 | if (!armv7_pmnc_counter_has_overflowed(pmnc, idx)) | ||
2052 | continue; | ||
2053 | |||
2054 | hwc = &event->hw; | ||
2055 | armpmu_event_update(event, hwc, idx); | ||
2056 | data.period = event->hw.last_period; | ||
2057 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
2058 | continue; | ||
2059 | |||
2060 | if (perf_event_overflow(event, 0, &data, regs)) | ||
2061 | armpmu->disable(hwc, idx); | ||
2062 | } | ||
2063 | |||
2064 | /* | ||
2065 | * Handle the pending perf events. | ||
2066 | * | ||
2067 | * Note: this call *must* be run with interrupts disabled. For | ||
2068 | * platforms that can have the PMU interrupts raised as an NMI, this | ||
2069 | * will not work. | ||
2070 | */ | ||
2071 | irq_work_run(); | ||
2072 | |||
2073 | return IRQ_HANDLED; | ||
2074 | } | ||
2075 | |||
2076 | static void armv7pmu_start(void) | ||
2077 | { | ||
2078 | unsigned long flags; | ||
2079 | |||
2080 | spin_lock_irqsave(&pmu_lock, flags); | ||
2081 | /* Enable all counters */ | ||
2082 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); | ||
2083 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2084 | } | ||
2085 | |||
2086 | static void armv7pmu_stop(void) | ||
2087 | { | ||
2088 | unsigned long flags; | ||
2089 | |||
2090 | spin_lock_irqsave(&pmu_lock, flags); | ||
2091 | /* Disable all counters */ | ||
2092 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); | ||
2093 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2094 | } | ||
2095 | |||
2096 | static inline int armv7_a8_pmu_event_map(int config) | ||
2097 | { | ||
2098 | int mapping = armv7_a8_perf_map[config]; | ||
2099 | if (HW_OP_UNSUPPORTED == mapping) | ||
2100 | mapping = -EOPNOTSUPP; | ||
2101 | return mapping; | ||
2102 | } | ||
2103 | |||
2104 | static inline int armv7_a9_pmu_event_map(int config) | ||
2105 | { | ||
2106 | int mapping = armv7_a9_perf_map[config]; | ||
2107 | if (HW_OP_UNSUPPORTED == mapping) | ||
2108 | mapping = -EOPNOTSUPP; | ||
2109 | return mapping; | ||
2110 | } | ||
2111 | |||
2112 | static u64 armv7pmu_raw_event(u64 config) | ||
2113 | { | ||
2114 | return config & 0xff; | ||
2115 | } | ||
2116 | |||
2117 | static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
2118 | struct hw_perf_event *event) | ||
2119 | { | ||
2120 | int idx; | ||
2121 | |||
2122 | /* Always place a cycle counter into the cycle counter. */ | ||
2123 | if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) { | ||
2124 | if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask)) | ||
2125 | return -EAGAIN; | ||
2126 | |||
2127 | return ARMV7_CYCLE_COUNTER; | ||
2128 | } else { | ||
2129 | /* | ||
2130 | * For anything other than a cycle counter, try and use | ||
2131 | * the events counters | ||
2132 | */ | ||
2133 | for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) { | ||
2134 | if (!test_and_set_bit(idx, cpuc->used_mask)) | ||
2135 | return idx; | ||
2136 | } | ||
2137 | |||
2138 | /* The counters are all in use. */ | ||
2139 | return -EAGAIN; | ||
2140 | } | ||
2141 | } | ||
2142 | |||
2143 | static struct arm_pmu armv7pmu = { | ||
2144 | .handle_irq = armv7pmu_handle_irq, | ||
2145 | .enable = armv7pmu_enable_event, | ||
2146 | .disable = armv7pmu_disable_event, | ||
2147 | .raw_event = armv7pmu_raw_event, | ||
2148 | .read_counter = armv7pmu_read_counter, | ||
2149 | .write_counter = armv7pmu_write_counter, | ||
2150 | .get_event_idx = armv7pmu_get_event_idx, | ||
2151 | .start = armv7pmu_start, | ||
2152 | .stop = armv7pmu_stop, | ||
2153 | .max_period = (1LLU << 32) - 1, | ||
2154 | }; | ||
2155 | |||
2156 | static u32 __init armv7_reset_read_pmnc(void) | ||
2157 | { | ||
2158 | u32 nb_cnt; | ||
2159 | |||
2160 | /* Initialize & Reset PMNC: C and P bits */ | ||
2161 | armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); | ||
2162 | |||
2163 | /* Read the nb of CNTx counters supported from PMNC */ | ||
2164 | nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; | ||
2165 | |||
2166 | /* Add the CPU cycles counter and return */ | ||
2167 | return nb_cnt + 1; | ||
2168 | } | ||
2169 | |||
2170 | /* | ||
2171 | * ARMv5 [xscale] Performance counter handling code. | ||
2172 | * | ||
2173 | * Based on xscale OProfile code. | ||
2174 | * | ||
2175 | * There are two variants of the xscale PMU that we support: | ||
2176 | * - xscale1pmu: 2 event counters and a cycle counter | ||
2177 | * - xscale2pmu: 4 event counters and a cycle counter | ||
2178 | * The two variants share event definitions, but have different | ||
2179 | * PMU structures. | ||
2180 | */ | ||
2181 | |||
2182 | enum xscale_perf_types { | ||
2183 | XSCALE_PERFCTR_ICACHE_MISS = 0x00, | ||
2184 | XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01, | ||
2185 | XSCALE_PERFCTR_DATA_STALL = 0x02, | ||
2186 | XSCALE_PERFCTR_ITLB_MISS = 0x03, | ||
2187 | XSCALE_PERFCTR_DTLB_MISS = 0x04, | ||
2188 | XSCALE_PERFCTR_BRANCH = 0x05, | ||
2189 | XSCALE_PERFCTR_BRANCH_MISS = 0x06, | ||
2190 | XSCALE_PERFCTR_INSTRUCTION = 0x07, | ||
2191 | XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08, | ||
2192 | XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09, | ||
2193 | XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A, | ||
2194 | XSCALE_PERFCTR_DCACHE_MISS = 0x0B, | ||
2195 | XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C, | ||
2196 | XSCALE_PERFCTR_PC_CHANGED = 0x0D, | ||
2197 | XSCALE_PERFCTR_BCU_REQUEST = 0x10, | ||
2198 | XSCALE_PERFCTR_BCU_FULL = 0x11, | ||
2199 | XSCALE_PERFCTR_BCU_DRAIN = 0x12, | ||
2200 | XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14, | ||
2201 | XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15, | ||
2202 | XSCALE_PERFCTR_RMW = 0x16, | ||
2203 | /* XSCALE_PERFCTR_CCNT is not hardware defined */ | ||
2204 | XSCALE_PERFCTR_CCNT = 0xFE, | ||
2205 | XSCALE_PERFCTR_UNUSED = 0xFF, | ||
2206 | }; | ||
2207 | |||
2208 | enum xscale_counters { | ||
2209 | XSCALE_CYCLE_COUNTER = 1, | ||
2210 | XSCALE_COUNTER0, | ||
2211 | XSCALE_COUNTER1, | ||
2212 | XSCALE_COUNTER2, | ||
2213 | XSCALE_COUNTER3, | ||
2214 | }; | ||
2215 | |||
2216 | static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = { | ||
2217 | [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT, | ||
2218 | [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION, | ||
2219 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
2220 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
2221 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH, | ||
2222 | [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS, | ||
2223 | [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, | ||
2224 | }; | ||
2225 | |||
2226 | static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
2227 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
2228 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
2229 | [C(L1D)] = { | ||
2230 | [C(OP_READ)] = { | ||
2231 | [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, | ||
2232 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, | ||
2233 | }, | ||
2234 | [C(OP_WRITE)] = { | ||
2235 | [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, | ||
2236 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, | ||
2237 | }, | ||
2238 | [C(OP_PREFETCH)] = { | ||
2239 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2240 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2241 | }, | ||
2242 | }, | ||
2243 | [C(L1I)] = { | ||
2244 | [C(OP_READ)] = { | ||
2245 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2246 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, | ||
2247 | }, | ||
2248 | [C(OP_WRITE)] = { | ||
2249 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2250 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, | ||
2251 | }, | ||
2252 | [C(OP_PREFETCH)] = { | ||
2253 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2254 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2255 | }, | ||
2256 | }, | ||
2257 | [C(LL)] = { | ||
2258 | [C(OP_READ)] = { | ||
2259 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2260 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2261 | }, | ||
2262 | [C(OP_WRITE)] = { | ||
2263 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2264 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2265 | }, | ||
2266 | [C(OP_PREFETCH)] = { | ||
2267 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2268 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2269 | }, | ||
2270 | }, | ||
2271 | [C(DTLB)] = { | ||
2272 | [C(OP_READ)] = { | ||
2273 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2274 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, | ||
2275 | }, | ||
2276 | [C(OP_WRITE)] = { | ||
2277 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2278 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, | ||
2279 | }, | ||
2280 | [C(OP_PREFETCH)] = { | ||
2281 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2282 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2283 | }, | ||
2284 | }, | ||
2285 | [C(ITLB)] = { | ||
2286 | [C(OP_READ)] = { | ||
2287 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2288 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, | ||
2289 | }, | ||
2290 | [C(OP_WRITE)] = { | ||
2291 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2292 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, | ||
2293 | }, | ||
2294 | [C(OP_PREFETCH)] = { | ||
2295 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2296 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2297 | }, | ||
2298 | }, | ||
2299 | [C(BPU)] = { | ||
2300 | [C(OP_READ)] = { | ||
2301 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2302 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2303 | }, | ||
2304 | [C(OP_WRITE)] = { | ||
2305 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2306 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2307 | }, | ||
2308 | [C(OP_PREFETCH)] = { | ||
2309 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
2310 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
2311 | }, | ||
2312 | }, | ||
2313 | }; | ||
2314 | |||
2315 | #define XSCALE_PMU_ENABLE 0x001 | ||
2316 | #define XSCALE_PMN_RESET 0x002 | ||
2317 | #define XSCALE_CCNT_RESET 0x004 | ||
2318 | #define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET) | ||
2319 | #define XSCALE_PMU_CNT64 0x008 | ||
2320 | |||
2321 | static inline int | ||
2322 | xscalepmu_event_map(int config) | ||
2323 | { | ||
2324 | int mapping = xscale_perf_map[config]; | ||
2325 | if (HW_OP_UNSUPPORTED == mapping) | ||
2326 | mapping = -EOPNOTSUPP; | ||
2327 | return mapping; | ||
2328 | } | ||
2329 | |||
2330 | static u64 | ||
2331 | xscalepmu_raw_event(u64 config) | ||
2332 | { | ||
2333 | return config & 0xff; | ||
2334 | } | ||
2335 | |||
2336 | #define XSCALE1_OVERFLOWED_MASK 0x700 | ||
2337 | #define XSCALE1_CCOUNT_OVERFLOW 0x400 | ||
2338 | #define XSCALE1_COUNT0_OVERFLOW 0x100 | ||
2339 | #define XSCALE1_COUNT1_OVERFLOW 0x200 | ||
2340 | #define XSCALE1_CCOUNT_INT_EN 0x040 | ||
2341 | #define XSCALE1_COUNT0_INT_EN 0x010 | ||
2342 | #define XSCALE1_COUNT1_INT_EN 0x020 | ||
2343 | #define XSCALE1_COUNT0_EVT_SHFT 12 | ||
2344 | #define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT) | ||
2345 | #define XSCALE1_COUNT1_EVT_SHFT 20 | ||
2346 | #define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT) | ||
2347 | |||
2348 | static inline u32 | ||
2349 | xscale1pmu_read_pmnc(void) | ||
2350 | { | ||
2351 | u32 val; | ||
2352 | asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val)); | ||
2353 | return val; | ||
2354 | } | ||
2355 | |||
2356 | static inline void | ||
2357 | xscale1pmu_write_pmnc(u32 val) | ||
2358 | { | ||
2359 | /* upper 4bits and 7, 11 are write-as-0 */ | ||
2360 | val &= 0xffff77f; | ||
2361 | asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val)); | ||
2362 | } | ||
2363 | |||
2364 | static inline int | ||
2365 | xscale1_pmnc_counter_has_overflowed(unsigned long pmnc, | ||
2366 | enum xscale_counters counter) | ||
2367 | { | ||
2368 | int ret = 0; | ||
2369 | |||
2370 | switch (counter) { | ||
2371 | case XSCALE_CYCLE_COUNTER: | ||
2372 | ret = pmnc & XSCALE1_CCOUNT_OVERFLOW; | ||
2373 | break; | ||
2374 | case XSCALE_COUNTER0: | ||
2375 | ret = pmnc & XSCALE1_COUNT0_OVERFLOW; | ||
2376 | break; | ||
2377 | case XSCALE_COUNTER1: | ||
2378 | ret = pmnc & XSCALE1_COUNT1_OVERFLOW; | ||
2379 | break; | ||
2380 | default: | ||
2381 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
2382 | } | ||
2383 | |||
2384 | return ret; | ||
2385 | } | ||
2386 | |||
2387 | static irqreturn_t | ||
2388 | xscale1pmu_handle_irq(int irq_num, void *dev) | ||
2389 | { | ||
2390 | unsigned long pmnc; | ||
2391 | struct perf_sample_data data; | ||
2392 | struct cpu_hw_events *cpuc; | ||
2393 | struct pt_regs *regs; | ||
2394 | int idx; | ||
2395 | |||
2396 | /* | ||
2397 | * NOTE: there's an A stepping erratum that states if an overflow | ||
2398 | * bit already exists and another occurs, the previous | ||
2399 | * Overflow bit gets cleared. There's no workaround. | ||
2400 | * Fixed in B stepping or later. | ||
2401 | */ | ||
2402 | pmnc = xscale1pmu_read_pmnc(); | ||
2403 | |||
2404 | /* | ||
2405 | * Write the value back to clear the overflow flags. Overflow | ||
2406 | * flags remain in pmnc for use below. We also disable the PMU | ||
2407 | * while we process the interrupt. | ||
2408 | */ | ||
2409 | xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); | ||
2410 | |||
2411 | if (!(pmnc & XSCALE1_OVERFLOWED_MASK)) | ||
2412 | return IRQ_NONE; | ||
2413 | |||
2414 | regs = get_irq_regs(); | ||
2415 | |||
2416 | perf_sample_data_init(&data, 0); | ||
2417 | |||
2418 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
2419 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
2420 | struct perf_event *event = cpuc->events[idx]; | ||
2421 | struct hw_perf_event *hwc; | ||
2422 | |||
2423 | if (!test_bit(idx, cpuc->active_mask)) | ||
2424 | continue; | ||
2425 | |||
2426 | if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx)) | ||
2427 | continue; | ||
2428 | |||
2429 | hwc = &event->hw; | ||
2430 | armpmu_event_update(event, hwc, idx); | ||
2431 | data.period = event->hw.last_period; | ||
2432 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
2433 | continue; | ||
2434 | |||
2435 | if (perf_event_overflow(event, 0, &data, regs)) | ||
2436 | armpmu->disable(hwc, idx); | ||
2437 | } | ||
2438 | |||
2439 | irq_work_run(); | ||
2440 | |||
2441 | /* | ||
2442 | * Re-enable the PMU. | ||
2443 | */ | ||
2444 | pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE; | ||
2445 | xscale1pmu_write_pmnc(pmnc); | ||
2446 | |||
2447 | return IRQ_HANDLED; | ||
2448 | } | ||
2449 | |||
2450 | static void | ||
2451 | xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) | ||
2452 | { | ||
2453 | unsigned long val, mask, evt, flags; | ||
2454 | |||
2455 | switch (idx) { | ||
2456 | case XSCALE_CYCLE_COUNTER: | ||
2457 | mask = 0; | ||
2458 | evt = XSCALE1_CCOUNT_INT_EN; | ||
2459 | break; | ||
2460 | case XSCALE_COUNTER0: | ||
2461 | mask = XSCALE1_COUNT0_EVT_MASK; | ||
2462 | evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) | | ||
2463 | XSCALE1_COUNT0_INT_EN; | ||
2464 | break; | ||
2465 | case XSCALE_COUNTER1: | ||
2466 | mask = XSCALE1_COUNT1_EVT_MASK; | ||
2467 | evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) | | ||
2468 | XSCALE1_COUNT1_INT_EN; | ||
2469 | break; | ||
2470 | default: | ||
2471 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
2472 | return; | ||
2473 | } | ||
2474 | |||
2475 | spin_lock_irqsave(&pmu_lock, flags); | ||
2476 | val = xscale1pmu_read_pmnc(); | ||
2477 | val &= ~mask; | ||
2478 | val |= evt; | ||
2479 | xscale1pmu_write_pmnc(val); | ||
2480 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2481 | } | ||
2482 | |||
2483 | static void | ||
2484 | xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) | ||
2485 | { | ||
2486 | unsigned long val, mask, evt, flags; | ||
2487 | |||
2488 | switch (idx) { | ||
2489 | case XSCALE_CYCLE_COUNTER: | ||
2490 | mask = XSCALE1_CCOUNT_INT_EN; | ||
2491 | evt = 0; | ||
2492 | break; | ||
2493 | case XSCALE_COUNTER0: | ||
2494 | mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK; | ||
2495 | evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT; | ||
2496 | break; | ||
2497 | case XSCALE_COUNTER1: | ||
2498 | mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK; | ||
2499 | evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT; | ||
2500 | break; | ||
2501 | default: | ||
2502 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
2503 | return; | ||
2504 | } | ||
2505 | |||
2506 | spin_lock_irqsave(&pmu_lock, flags); | ||
2507 | val = xscale1pmu_read_pmnc(); | ||
2508 | val &= ~mask; | ||
2509 | val |= evt; | ||
2510 | xscale1pmu_write_pmnc(val); | ||
2511 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2512 | } | ||
2513 | |||
2514 | static int | ||
2515 | xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
2516 | struct hw_perf_event *event) | ||
2517 | { | ||
2518 | if (XSCALE_PERFCTR_CCNT == event->config_base) { | ||
2519 | if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask)) | ||
2520 | return -EAGAIN; | ||
2521 | |||
2522 | return XSCALE_CYCLE_COUNTER; | ||
2523 | } else { | ||
2524 | if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) { | ||
2525 | return XSCALE_COUNTER1; | ||
2526 | } | ||
2527 | |||
2528 | if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) { | ||
2529 | return XSCALE_COUNTER0; | ||
2530 | } | ||
2531 | |||
2532 | return -EAGAIN; | ||
2533 | } | ||
2534 | } | ||
2535 | |||
2536 | static void | ||
2537 | xscale1pmu_start(void) | ||
2538 | { | ||
2539 | unsigned long flags, val; | ||
2540 | |||
2541 | spin_lock_irqsave(&pmu_lock, flags); | ||
2542 | val = xscale1pmu_read_pmnc(); | ||
2543 | val |= XSCALE_PMU_ENABLE; | ||
2544 | xscale1pmu_write_pmnc(val); | ||
2545 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2546 | } | ||
2547 | |||
2548 | static void | ||
2549 | xscale1pmu_stop(void) | ||
2550 | { | ||
2551 | unsigned long flags, val; | ||
2552 | |||
2553 | spin_lock_irqsave(&pmu_lock, flags); | ||
2554 | val = xscale1pmu_read_pmnc(); | ||
2555 | val &= ~XSCALE_PMU_ENABLE; | ||
2556 | xscale1pmu_write_pmnc(val); | ||
2557 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2558 | } | ||
2559 | |||
2560 | static inline u32 | ||
2561 | xscale1pmu_read_counter(int counter) | ||
2562 | { | ||
2563 | u32 val = 0; | ||
2564 | |||
2565 | switch (counter) { | ||
2566 | case XSCALE_CYCLE_COUNTER: | ||
2567 | asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val)); | ||
2568 | break; | ||
2569 | case XSCALE_COUNTER0: | ||
2570 | asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val)); | ||
2571 | break; | ||
2572 | case XSCALE_COUNTER1: | ||
2573 | asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val)); | ||
2574 | break; | ||
2575 | } | ||
2576 | |||
2577 | return val; | ||
2578 | } | ||
2579 | |||
2580 | static inline void | ||
2581 | xscale1pmu_write_counter(int counter, u32 val) | ||
2582 | { | ||
2583 | switch (counter) { | ||
2584 | case XSCALE_CYCLE_COUNTER: | ||
2585 | asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val)); | ||
2586 | break; | ||
2587 | case XSCALE_COUNTER0: | ||
2588 | asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val)); | ||
2589 | break; | ||
2590 | case XSCALE_COUNTER1: | ||
2591 | asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val)); | ||
2592 | break; | ||
2593 | } | ||
2594 | } | ||
2595 | |||
2596 | static const struct arm_pmu xscale1pmu = { | ||
2597 | .id = ARM_PERF_PMU_ID_XSCALE1, | ||
2598 | .handle_irq = xscale1pmu_handle_irq, | ||
2599 | .enable = xscale1pmu_enable_event, | ||
2600 | .disable = xscale1pmu_disable_event, | ||
2601 | .event_map = xscalepmu_event_map, | ||
2602 | .raw_event = xscalepmu_raw_event, | ||
2603 | .read_counter = xscale1pmu_read_counter, | ||
2604 | .write_counter = xscale1pmu_write_counter, | ||
2605 | .get_event_idx = xscale1pmu_get_event_idx, | ||
2606 | .start = xscale1pmu_start, | ||
2607 | .stop = xscale1pmu_stop, | ||
2608 | .num_events = 3, | ||
2609 | .max_period = (1LLU << 32) - 1, | ||
2610 | }; | ||
2611 | |||
2612 | #define XSCALE2_OVERFLOWED_MASK 0x01f | ||
2613 | #define XSCALE2_CCOUNT_OVERFLOW 0x001 | ||
2614 | #define XSCALE2_COUNT0_OVERFLOW 0x002 | ||
2615 | #define XSCALE2_COUNT1_OVERFLOW 0x004 | ||
2616 | #define XSCALE2_COUNT2_OVERFLOW 0x008 | ||
2617 | #define XSCALE2_COUNT3_OVERFLOW 0x010 | ||
2618 | #define XSCALE2_CCOUNT_INT_EN 0x001 | ||
2619 | #define XSCALE2_COUNT0_INT_EN 0x002 | ||
2620 | #define XSCALE2_COUNT1_INT_EN 0x004 | ||
2621 | #define XSCALE2_COUNT2_INT_EN 0x008 | ||
2622 | #define XSCALE2_COUNT3_INT_EN 0x010 | ||
2623 | #define XSCALE2_COUNT0_EVT_SHFT 0 | ||
2624 | #define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT) | ||
2625 | #define XSCALE2_COUNT1_EVT_SHFT 8 | ||
2626 | #define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT) | ||
2627 | #define XSCALE2_COUNT2_EVT_SHFT 16 | ||
2628 | #define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT) | ||
2629 | #define XSCALE2_COUNT3_EVT_SHFT 24 | ||
2630 | #define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT) | ||
2631 | |||
2632 | static inline u32 | ||
2633 | xscale2pmu_read_pmnc(void) | ||
2634 | { | ||
2635 | u32 val; | ||
2636 | asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val)); | ||
2637 | /* bits 1-2 and 4-23 are read-unpredictable */ | ||
2638 | return val & 0xff000009; | ||
2639 | } | ||
2640 | |||
2641 | static inline void | ||
2642 | xscale2pmu_write_pmnc(u32 val) | ||
2643 | { | ||
2644 | /* bits 4-23 are write-as-0, 24-31 are write ignored */ | ||
2645 | val &= 0xf; | ||
2646 | asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val)); | ||
2647 | } | ||
2648 | |||
2649 | static inline u32 | ||
2650 | xscale2pmu_read_overflow_flags(void) | ||
2651 | { | ||
2652 | u32 val; | ||
2653 | asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val)); | ||
2654 | return val; | ||
2655 | } | ||
2656 | |||
2657 | static inline void | ||
2658 | xscale2pmu_write_overflow_flags(u32 val) | ||
2659 | { | ||
2660 | asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val)); | ||
2661 | } | ||
2662 | |||
2663 | static inline u32 | ||
2664 | xscale2pmu_read_event_select(void) | ||
2665 | { | ||
2666 | u32 val; | ||
2667 | asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val)); | ||
2668 | return val; | ||
2669 | } | ||
2670 | |||
2671 | static inline void | ||
2672 | xscale2pmu_write_event_select(u32 val) | ||
2673 | { | ||
2674 | asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val)); | ||
2675 | } | ||
2676 | |||
2677 | static inline u32 | ||
2678 | xscale2pmu_read_int_enable(void) | ||
2679 | { | ||
2680 | u32 val; | ||
2681 | asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val)); | ||
2682 | return val; | ||
2683 | } | ||
2684 | |||
2685 | static void | ||
2686 | xscale2pmu_write_int_enable(u32 val) | ||
2687 | { | ||
2688 | asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val)); | ||
2689 | } | ||
2690 | |||
2691 | static inline int | ||
2692 | xscale2_pmnc_counter_has_overflowed(unsigned long of_flags, | ||
2693 | enum xscale_counters counter) | ||
2694 | { | ||
2695 | int ret = 0; | ||
2696 | |||
2697 | switch (counter) { | ||
2698 | case XSCALE_CYCLE_COUNTER: | ||
2699 | ret = of_flags & XSCALE2_CCOUNT_OVERFLOW; | ||
2700 | break; | ||
2701 | case XSCALE_COUNTER0: | ||
2702 | ret = of_flags & XSCALE2_COUNT0_OVERFLOW; | ||
2703 | break; | ||
2704 | case XSCALE_COUNTER1: | ||
2705 | ret = of_flags & XSCALE2_COUNT1_OVERFLOW; | ||
2706 | break; | ||
2707 | case XSCALE_COUNTER2: | ||
2708 | ret = of_flags & XSCALE2_COUNT2_OVERFLOW; | ||
2709 | break; | ||
2710 | case XSCALE_COUNTER3: | ||
2711 | ret = of_flags & XSCALE2_COUNT3_OVERFLOW; | ||
2712 | break; | ||
2713 | default: | ||
2714 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
2715 | } | ||
2716 | |||
2717 | return ret; | ||
2718 | } | ||
2719 | |||
2720 | static irqreturn_t | ||
2721 | xscale2pmu_handle_irq(int irq_num, void *dev) | ||
2722 | { | ||
2723 | unsigned long pmnc, of_flags; | ||
2724 | struct perf_sample_data data; | ||
2725 | struct cpu_hw_events *cpuc; | ||
2726 | struct pt_regs *regs; | ||
2727 | int idx; | ||
2728 | |||
2729 | /* Disable the PMU. */ | ||
2730 | pmnc = xscale2pmu_read_pmnc(); | ||
2731 | xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); | ||
2732 | |||
2733 | /* Check the overflow flag register. */ | ||
2734 | of_flags = xscale2pmu_read_overflow_flags(); | ||
2735 | if (!(of_flags & XSCALE2_OVERFLOWED_MASK)) | ||
2736 | return IRQ_NONE; | ||
2737 | |||
2738 | /* Clear the overflow bits. */ | ||
2739 | xscale2pmu_write_overflow_flags(of_flags); | ||
2740 | |||
2741 | regs = get_irq_regs(); | ||
2742 | |||
2743 | perf_sample_data_init(&data, 0); | ||
2744 | |||
2745 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
2746 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
2747 | struct perf_event *event = cpuc->events[idx]; | ||
2748 | struct hw_perf_event *hwc; | ||
2749 | |||
2750 | if (!test_bit(idx, cpuc->active_mask)) | ||
2751 | continue; | ||
2752 | |||
2753 | if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx)) | ||
2754 | continue; | ||
2755 | |||
2756 | hwc = &event->hw; | ||
2757 | armpmu_event_update(event, hwc, idx); | ||
2758 | data.period = event->hw.last_period; | ||
2759 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
2760 | continue; | ||
2761 | |||
2762 | if (perf_event_overflow(event, 0, &data, regs)) | ||
2763 | armpmu->disable(hwc, idx); | ||
2764 | } | ||
2765 | |||
2766 | irq_work_run(); | ||
2767 | |||
2768 | /* | ||
2769 | * Re-enable the PMU. | ||
2770 | */ | ||
2771 | pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE; | ||
2772 | xscale2pmu_write_pmnc(pmnc); | ||
2773 | |||
2774 | return IRQ_HANDLED; | ||
2775 | } | ||
2776 | |||
2777 | static void | ||
2778 | xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) | ||
2779 | { | ||
2780 | unsigned long flags, ien, evtsel; | ||
2781 | |||
2782 | ien = xscale2pmu_read_int_enable(); | ||
2783 | evtsel = xscale2pmu_read_event_select(); | ||
2784 | |||
2785 | switch (idx) { | ||
2786 | case XSCALE_CYCLE_COUNTER: | ||
2787 | ien |= XSCALE2_CCOUNT_INT_EN; | ||
2788 | break; | ||
2789 | case XSCALE_COUNTER0: | ||
2790 | ien |= XSCALE2_COUNT0_INT_EN; | ||
2791 | evtsel &= ~XSCALE2_COUNT0_EVT_MASK; | ||
2792 | evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT; | ||
2793 | break; | ||
2794 | case XSCALE_COUNTER1: | ||
2795 | ien |= XSCALE2_COUNT1_INT_EN; | ||
2796 | evtsel &= ~XSCALE2_COUNT1_EVT_MASK; | ||
2797 | evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT; | ||
2798 | break; | ||
2799 | case XSCALE_COUNTER2: | ||
2800 | ien |= XSCALE2_COUNT2_INT_EN; | ||
2801 | evtsel &= ~XSCALE2_COUNT2_EVT_MASK; | ||
2802 | evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT; | ||
2803 | break; | ||
2804 | case XSCALE_COUNTER3: | ||
2805 | ien |= XSCALE2_COUNT3_INT_EN; | ||
2806 | evtsel &= ~XSCALE2_COUNT3_EVT_MASK; | ||
2807 | evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT; | ||
2808 | break; | ||
2809 | default: | ||
2810 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
2811 | return; | ||
2812 | } | ||
2813 | |||
2814 | spin_lock_irqsave(&pmu_lock, flags); | ||
2815 | xscale2pmu_write_event_select(evtsel); | ||
2816 | xscale2pmu_write_int_enable(ien); | ||
2817 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2818 | } | ||
2819 | |||
2820 | static void | ||
2821 | xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) | ||
2822 | { | ||
2823 | unsigned long flags, ien, evtsel; | ||
2824 | |||
2825 | ien = xscale2pmu_read_int_enable(); | ||
2826 | evtsel = xscale2pmu_read_event_select(); | ||
2827 | |||
2828 | switch (idx) { | ||
2829 | case XSCALE_CYCLE_COUNTER: | ||
2830 | ien &= ~XSCALE2_CCOUNT_INT_EN; | ||
2831 | break; | ||
2832 | case XSCALE_COUNTER0: | ||
2833 | ien &= ~XSCALE2_COUNT0_INT_EN; | ||
2834 | evtsel &= ~XSCALE2_COUNT0_EVT_MASK; | ||
2835 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT; | ||
2836 | break; | ||
2837 | case XSCALE_COUNTER1: | ||
2838 | ien &= ~XSCALE2_COUNT1_INT_EN; | ||
2839 | evtsel &= ~XSCALE2_COUNT1_EVT_MASK; | ||
2840 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT; | ||
2841 | break; | ||
2842 | case XSCALE_COUNTER2: | ||
2843 | ien &= ~XSCALE2_COUNT2_INT_EN; | ||
2844 | evtsel &= ~XSCALE2_COUNT2_EVT_MASK; | ||
2845 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT; | ||
2846 | break; | ||
2847 | case XSCALE_COUNTER3: | ||
2848 | ien &= ~XSCALE2_COUNT3_INT_EN; | ||
2849 | evtsel &= ~XSCALE2_COUNT3_EVT_MASK; | ||
2850 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT; | ||
2851 | break; | ||
2852 | default: | ||
2853 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
2854 | return; | ||
2855 | } | ||
2856 | |||
2857 | spin_lock_irqsave(&pmu_lock, flags); | ||
2858 | xscale2pmu_write_event_select(evtsel); | ||
2859 | xscale2pmu_write_int_enable(ien); | ||
2860 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2861 | } | ||
2862 | |||
2863 | static int | ||
2864 | xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
2865 | struct hw_perf_event *event) | ||
2866 | { | ||
2867 | int idx = xscale1pmu_get_event_idx(cpuc, event); | ||
2868 | if (idx >= 0) | ||
2869 | goto out; | ||
2870 | |||
2871 | if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask)) | ||
2872 | idx = XSCALE_COUNTER3; | ||
2873 | else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask)) | ||
2874 | idx = XSCALE_COUNTER2; | ||
2875 | out: | ||
2876 | return idx; | ||
2877 | } | ||
2878 | |||
2879 | static void | ||
2880 | xscale2pmu_start(void) | ||
2881 | { | ||
2882 | unsigned long flags, val; | ||
2883 | |||
2884 | spin_lock_irqsave(&pmu_lock, flags); | ||
2885 | val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; | ||
2886 | val |= XSCALE_PMU_ENABLE; | ||
2887 | xscale2pmu_write_pmnc(val); | ||
2888 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2889 | } | ||
2890 | |||
2891 | static void | ||
2892 | xscale2pmu_stop(void) | ||
2893 | { | ||
2894 | unsigned long flags, val; | ||
2895 | |||
2896 | spin_lock_irqsave(&pmu_lock, flags); | ||
2897 | val = xscale2pmu_read_pmnc(); | ||
2898 | val &= ~XSCALE_PMU_ENABLE; | ||
2899 | xscale2pmu_write_pmnc(val); | ||
2900 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2901 | } | ||
2902 | |||
2903 | static inline u32 | ||
2904 | xscale2pmu_read_counter(int counter) | ||
2905 | { | ||
2906 | u32 val = 0; | ||
2907 | |||
2908 | switch (counter) { | ||
2909 | case XSCALE_CYCLE_COUNTER: | ||
2910 | asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val)); | ||
2911 | break; | ||
2912 | case XSCALE_COUNTER0: | ||
2913 | asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val)); | ||
2914 | break; | ||
2915 | case XSCALE_COUNTER1: | ||
2916 | asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val)); | ||
2917 | break; | ||
2918 | case XSCALE_COUNTER2: | ||
2919 | asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val)); | ||
2920 | break; | ||
2921 | case XSCALE_COUNTER3: | ||
2922 | asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val)); | ||
2923 | break; | ||
2924 | } | ||
2925 | |||
2926 | return val; | ||
2927 | } | ||
2928 | |||
2929 | static inline void | ||
2930 | xscale2pmu_write_counter(int counter, u32 val) | ||
2931 | { | ||
2932 | switch (counter) { | ||
2933 | case XSCALE_CYCLE_COUNTER: | ||
2934 | asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val)); | ||
2935 | break; | ||
2936 | case XSCALE_COUNTER0: | ||
2937 | asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val)); | ||
2938 | break; | ||
2939 | case XSCALE_COUNTER1: | ||
2940 | asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val)); | ||
2941 | break; | ||
2942 | case XSCALE_COUNTER2: | ||
2943 | asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val)); | ||
2944 | break; | ||
2945 | case XSCALE_COUNTER3: | ||
2946 | asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val)); | ||
2947 | break; | ||
2948 | } | ||
2949 | } | ||
2950 | |||
2951 | static const struct arm_pmu xscale2pmu = { | ||
2952 | .id = ARM_PERF_PMU_ID_XSCALE2, | ||
2953 | .handle_irq = xscale2pmu_handle_irq, | ||
2954 | .enable = xscale2pmu_enable_event, | ||
2955 | .disable = xscale2pmu_disable_event, | ||
2956 | .event_map = xscalepmu_event_map, | ||
2957 | .raw_event = xscalepmu_raw_event, | ||
2958 | .read_counter = xscale2pmu_read_counter, | ||
2959 | .write_counter = xscale2pmu_write_counter, | ||
2960 | .get_event_idx = xscale2pmu_get_event_idx, | ||
2961 | .start = xscale2pmu_start, | ||
2962 | .stop = xscale2pmu_stop, | ||
2963 | .num_events = 5, | ||
2964 | .max_period = (1LLU << 32) - 1, | ||
2965 | }; | ||
2966 | 611 | ||
2967 | static int __init | 612 | static int __init |
2968 | init_hw_perf_events(void) | 613 | init_hw_perf_events(void) |
@@ -2977,37 +622,16 @@ init_hw_perf_events(void) | |||
2977 | case 0xB360: /* ARM1136 */ | 622 | case 0xB360: /* ARM1136 */ |
2978 | case 0xB560: /* ARM1156 */ | 623 | case 0xB560: /* ARM1156 */ |
2979 | case 0xB760: /* ARM1176 */ | 624 | case 0xB760: /* ARM1176 */ |
2980 | armpmu = &armv6pmu; | 625 | armpmu = armv6pmu_init(); |
2981 | memcpy(armpmu_perf_cache_map, armv6_perf_cache_map, | ||
2982 | sizeof(armv6_perf_cache_map)); | ||
2983 | break; | 626 | break; |
2984 | case 0xB020: /* ARM11mpcore */ | 627 | case 0xB020: /* ARM11mpcore */ |
2985 | armpmu = &armv6mpcore_pmu; | 628 | armpmu = armv6mpcore_pmu_init(); |
2986 | memcpy(armpmu_perf_cache_map, | ||
2987 | armv6mpcore_perf_cache_map, | ||
2988 | sizeof(armv6mpcore_perf_cache_map)); | ||
2989 | break; | 629 | break; |
2990 | case 0xC080: /* Cortex-A8 */ | 630 | case 0xC080: /* Cortex-A8 */ |
2991 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; | 631 | armpmu = armv7_a8_pmu_init(); |
2992 | memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map, | ||
2993 | sizeof(armv7_a8_perf_cache_map)); | ||
2994 | armv7pmu.event_map = armv7_a8_pmu_event_map; | ||
2995 | armpmu = &armv7pmu; | ||
2996 | |||
2997 | /* Reset PMNC and read the nb of CNTx counters | ||
2998 | supported */ | ||
2999 | armv7pmu.num_events = armv7_reset_read_pmnc(); | ||
3000 | break; | 632 | break; |
3001 | case 0xC090: /* Cortex-A9 */ | 633 | case 0xC090: /* Cortex-A9 */ |
3002 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; | 634 | armpmu = armv7_a9_pmu_init(); |
3003 | memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map, | ||
3004 | sizeof(armv7_a9_perf_cache_map)); | ||
3005 | armv7pmu.event_map = armv7_a9_pmu_event_map; | ||
3006 | armpmu = &armv7pmu; | ||
3007 | |||
3008 | /* Reset PMNC and read the nb of CNTx counters | ||
3009 | supported */ | ||
3010 | armv7pmu.num_events = armv7_reset_read_pmnc(); | ||
3011 | break; | 635 | break; |
3012 | } | 636 | } |
3013 | /* Intel CPUs [xscale]. */ | 637 | /* Intel CPUs [xscale]. */ |
@@ -3015,21 +639,17 @@ init_hw_perf_events(void) | |||
3015 | part_number = (cpuid >> 13) & 0x7; | 639 | part_number = (cpuid >> 13) & 0x7; |
3016 | switch (part_number) { | 640 | switch (part_number) { |
3017 | case 1: | 641 | case 1: |
3018 | armpmu = &xscale1pmu; | 642 | armpmu = xscale1pmu_init(); |
3019 | memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, | ||
3020 | sizeof(xscale_perf_cache_map)); | ||
3021 | break; | 643 | break; |
3022 | case 2: | 644 | case 2: |
3023 | armpmu = &xscale2pmu; | 645 | armpmu = xscale2pmu_init(); |
3024 | memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, | ||
3025 | sizeof(xscale_perf_cache_map)); | ||
3026 | break; | 646 | break; |
3027 | } | 647 | } |
3028 | } | 648 | } |
3029 | 649 | ||
3030 | if (armpmu) { | 650 | if (armpmu) { |
3031 | pr_info("enabled with %s PMU driver, %d counters available\n", | 651 | pr_info("enabled with %s PMU driver, %d counters available\n", |
3032 | arm_pmu_names[armpmu->id], armpmu->num_events); | 652 | armpmu->name, armpmu->num_events); |
3033 | } else { | 653 | } else { |
3034 | pr_info("no hardware support available\n"); | 654 | pr_info("no hardware support available\n"); |
3035 | } | 655 | } |
@@ -3053,17 +673,17 @@ arch_initcall(init_hw_perf_events); | |||
3053 | * This code has been adapted from the ARM OProfile support. | 673 | * This code has been adapted from the ARM OProfile support. |
3054 | */ | 674 | */ |
3055 | struct frame_tail { | 675 | struct frame_tail { |
3056 | struct frame_tail *fp; | 676 | struct frame_tail __user *fp; |
3057 | unsigned long sp; | 677 | unsigned long sp; |
3058 | unsigned long lr; | 678 | unsigned long lr; |
3059 | } __attribute__((packed)); | 679 | } __attribute__((packed)); |
3060 | 680 | ||
3061 | /* | 681 | /* |
3062 | * Get the return address for a single stackframe and return a pointer to the | 682 | * Get the return address for a single stackframe and return a pointer to the |
3063 | * next frame tail. | 683 | * next frame tail. |
3064 | */ | 684 | */ |
3065 | static struct frame_tail * | 685 | static struct frame_tail __user * |
3066 | user_backtrace(struct frame_tail *tail, | 686 | user_backtrace(struct frame_tail __user *tail, |
3067 | struct perf_callchain_entry *entry) | 687 | struct perf_callchain_entry *entry) |
3068 | { | 688 | { |
3069 | struct frame_tail buftail; | 689 | struct frame_tail buftail; |
@@ -3089,10 +709,10 @@ user_backtrace(struct frame_tail *tail, | |||
3089 | void | 709 | void |
3090 | perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) | 710 | perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) |
3091 | { | 711 | { |
3092 | struct frame_tail *tail; | 712 | struct frame_tail __user *tail; |
3093 | 713 | ||
3094 | 714 | ||
3095 | tail = (struct frame_tail *)regs->ARM_fp - 1; | 715 | tail = (struct frame_tail __user *)regs->ARM_fp - 1; |
3096 | 716 | ||
3097 | while (tail && !((unsigned long)tail & 0x3)) | 717 | while (tail && !((unsigned long)tail & 0x3)) |
3098 | tail = user_backtrace(tail, entry); | 718 | tail = user_backtrace(tail, entry); |
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c new file mode 100644 index 000000000000..c058bfc8532b --- /dev/null +++ b/arch/arm/kernel/perf_event_v6.c | |||
@@ -0,0 +1,672 @@ | |||
1 | /* | ||
2 | * ARMv6 Performance counter handling code. | ||
3 | * | ||
4 | * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles | ||
5 | * | ||
6 | * ARMv6 has 2 configurable performance counters and a single cycle counter. | ||
7 | * They all share a single reset bit but can be written to zero so we can use | ||
8 | * that for a reset. | ||
9 | * | ||
10 | * The counters can't be individually enabled or disabled so when we remove | ||
11 | * one event and replace it with another we could get spurious counts from the | ||
12 | * wrong event. However, we can take advantage of the fact that the | ||
13 | * performance counters can export events to the event bus, and the event bus | ||
14 | * itself can be monitored. This requires that we *don't* export the events to | ||
15 | * the event bus. The procedure for disabling a configurable counter is: | ||
16 | * - change the counter to count the ETMEXTOUT[0] signal (0x20). This | ||
17 | * effectively stops the counter from counting. | ||
18 | * - disable the counter's interrupt generation (each counter has it's | ||
19 | * own interrupt enable bit). | ||
20 | * Once stopped, the counter value can be written as 0 to reset. | ||
21 | * | ||
22 | * To enable a counter: | ||
23 | * - enable the counter's interrupt generation. | ||
24 | * - set the new event type. | ||
25 | * | ||
26 | * Note: the dedicated cycle counter only counts cycles and can't be | ||
27 | * enabled/disabled independently of the others. When we want to disable the | ||
28 | * cycle counter, we have to just disable the interrupt reporting and start | ||
29 | * ignoring that counter. When re-enabling, we have to reset the value and | ||
30 | * enable the interrupt. | ||
31 | */ | ||
32 | |||
33 | #ifdef CONFIG_CPU_V6 | ||
34 | enum armv6_perf_types { | ||
35 | ARMV6_PERFCTR_ICACHE_MISS = 0x0, | ||
36 | ARMV6_PERFCTR_IBUF_STALL = 0x1, | ||
37 | ARMV6_PERFCTR_DDEP_STALL = 0x2, | ||
38 | ARMV6_PERFCTR_ITLB_MISS = 0x3, | ||
39 | ARMV6_PERFCTR_DTLB_MISS = 0x4, | ||
40 | ARMV6_PERFCTR_BR_EXEC = 0x5, | ||
41 | ARMV6_PERFCTR_BR_MISPREDICT = 0x6, | ||
42 | ARMV6_PERFCTR_INSTR_EXEC = 0x7, | ||
43 | ARMV6_PERFCTR_DCACHE_HIT = 0x9, | ||
44 | ARMV6_PERFCTR_DCACHE_ACCESS = 0xA, | ||
45 | ARMV6_PERFCTR_DCACHE_MISS = 0xB, | ||
46 | ARMV6_PERFCTR_DCACHE_WBACK = 0xC, | ||
47 | ARMV6_PERFCTR_SW_PC_CHANGE = 0xD, | ||
48 | ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF, | ||
49 | ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10, | ||
50 | ARMV6_PERFCTR_LSU_FULL_STALL = 0x11, | ||
51 | ARMV6_PERFCTR_WBUF_DRAINED = 0x12, | ||
52 | ARMV6_PERFCTR_CPU_CYCLES = 0xFF, | ||
53 | ARMV6_PERFCTR_NOP = 0x20, | ||
54 | }; | ||
55 | |||
56 | enum armv6_counters { | ||
57 | ARMV6_CYCLE_COUNTER = 1, | ||
58 | ARMV6_COUNTER0, | ||
59 | ARMV6_COUNTER1, | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | * The hardware events that we support. We do support cache operations but | ||
64 | * we have harvard caches and no way to combine instruction and data | ||
65 | * accesses/misses in hardware. | ||
66 | */ | ||
67 | static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = { | ||
68 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES, | ||
69 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC, | ||
70 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
71 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
72 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC, | ||
73 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT, | ||
74 | [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, | ||
75 | }; | ||
76 | |||
77 | static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
78 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
79 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
80 | [C(L1D)] = { | ||
81 | /* | ||
82 | * The performance counters don't differentiate between read | ||
83 | * and write accesses/misses so this isn't strictly correct, | ||
84 | * but it's the best we can do. Writes and reads get | ||
85 | * combined. | ||
86 | */ | ||
87 | [C(OP_READ)] = { | ||
88 | [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS, | ||
89 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS, | ||
90 | }, | ||
91 | [C(OP_WRITE)] = { | ||
92 | [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS, | ||
93 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS, | ||
94 | }, | ||
95 | [C(OP_PREFETCH)] = { | ||
96 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
97 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
98 | }, | ||
99 | }, | ||
100 | [C(L1I)] = { | ||
101 | [C(OP_READ)] = { | ||
102 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
103 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS, | ||
104 | }, | ||
105 | [C(OP_WRITE)] = { | ||
106 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
107 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS, | ||
108 | }, | ||
109 | [C(OP_PREFETCH)] = { | ||
110 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
111 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
112 | }, | ||
113 | }, | ||
114 | [C(LL)] = { | ||
115 | [C(OP_READ)] = { | ||
116 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
117 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
118 | }, | ||
119 | [C(OP_WRITE)] = { | ||
120 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
121 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
122 | }, | ||
123 | [C(OP_PREFETCH)] = { | ||
124 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
125 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
126 | }, | ||
127 | }, | ||
128 | [C(DTLB)] = { | ||
129 | /* | ||
130 | * The ARM performance counters can count micro DTLB misses, | ||
131 | * micro ITLB misses and main TLB misses. There isn't an event | ||
132 | * for TLB misses, so use the micro misses here and if users | ||
133 | * want the main TLB misses they can use a raw counter. | ||
134 | */ | ||
135 | [C(OP_READ)] = { | ||
136 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
137 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS, | ||
138 | }, | ||
139 | [C(OP_WRITE)] = { | ||
140 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
141 | [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS, | ||
142 | }, | ||
143 | [C(OP_PREFETCH)] = { | ||
144 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
145 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
146 | }, | ||
147 | }, | ||
148 | [C(ITLB)] = { | ||
149 | [C(OP_READ)] = { | ||
150 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
151 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS, | ||
152 | }, | ||
153 | [C(OP_WRITE)] = { | ||
154 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
155 | [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS, | ||
156 | }, | ||
157 | [C(OP_PREFETCH)] = { | ||
158 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
159 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
160 | }, | ||
161 | }, | ||
162 | [C(BPU)] = { | ||
163 | [C(OP_READ)] = { | ||
164 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
165 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
166 | }, | ||
167 | [C(OP_WRITE)] = { | ||
168 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
169 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
170 | }, | ||
171 | [C(OP_PREFETCH)] = { | ||
172 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
173 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
174 | }, | ||
175 | }, | ||
176 | }; | ||
177 | |||
178 | enum armv6mpcore_perf_types { | ||
179 | ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0, | ||
180 | ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1, | ||
181 | ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2, | ||
182 | ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3, | ||
183 | ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4, | ||
184 | ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5, | ||
185 | ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6, | ||
186 | ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7, | ||
187 | ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8, | ||
188 | ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA, | ||
189 | ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB, | ||
190 | ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC, | ||
191 | ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD, | ||
192 | ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE, | ||
193 | ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF, | ||
194 | ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10, | ||
195 | ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11, | ||
196 | ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12, | ||
197 | ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13, | ||
198 | ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF, | ||
199 | }; | ||
200 | |||
201 | /* | ||
202 | * The hardware events that we support. We do support cache operations but | ||
203 | * we have harvard caches and no way to combine instruction and data | ||
204 | * accesses/misses in hardware. | ||
205 | */ | ||
206 | static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = { | ||
207 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES, | ||
208 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC, | ||
209 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
210 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
211 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC, | ||
212 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT, | ||
213 | [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, | ||
214 | }; | ||
215 | |||
216 | static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
217 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
218 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
219 | [C(L1D)] = { | ||
220 | [C(OP_READ)] = { | ||
221 | [C(RESULT_ACCESS)] = | ||
222 | ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS, | ||
223 | [C(RESULT_MISS)] = | ||
224 | ARMV6MPCORE_PERFCTR_DCACHE_RDMISS, | ||
225 | }, | ||
226 | [C(OP_WRITE)] = { | ||
227 | [C(RESULT_ACCESS)] = | ||
228 | ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS, | ||
229 | [C(RESULT_MISS)] = | ||
230 | ARMV6MPCORE_PERFCTR_DCACHE_WRMISS, | ||
231 | }, | ||
232 | [C(OP_PREFETCH)] = { | ||
233 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
234 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
235 | }, | ||
236 | }, | ||
237 | [C(L1I)] = { | ||
238 | [C(OP_READ)] = { | ||
239 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
240 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS, | ||
241 | }, | ||
242 | [C(OP_WRITE)] = { | ||
243 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
244 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS, | ||
245 | }, | ||
246 | [C(OP_PREFETCH)] = { | ||
247 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
248 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
249 | }, | ||
250 | }, | ||
251 | [C(LL)] = { | ||
252 | [C(OP_READ)] = { | ||
253 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
254 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
255 | }, | ||
256 | [C(OP_WRITE)] = { | ||
257 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
258 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
259 | }, | ||
260 | [C(OP_PREFETCH)] = { | ||
261 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
262 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
263 | }, | ||
264 | }, | ||
265 | [C(DTLB)] = { | ||
266 | /* | ||
267 | * The ARM performance counters can count micro DTLB misses, | ||
268 | * micro ITLB misses and main TLB misses. There isn't an event | ||
269 | * for TLB misses, so use the micro misses here and if users | ||
270 | * want the main TLB misses they can use a raw counter. | ||
271 | */ | ||
272 | [C(OP_READ)] = { | ||
273 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
274 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS, | ||
275 | }, | ||
276 | [C(OP_WRITE)] = { | ||
277 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
278 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS, | ||
279 | }, | ||
280 | [C(OP_PREFETCH)] = { | ||
281 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
282 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
283 | }, | ||
284 | }, | ||
285 | [C(ITLB)] = { | ||
286 | [C(OP_READ)] = { | ||
287 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
288 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS, | ||
289 | }, | ||
290 | [C(OP_WRITE)] = { | ||
291 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
292 | [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS, | ||
293 | }, | ||
294 | [C(OP_PREFETCH)] = { | ||
295 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
296 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
297 | }, | ||
298 | }, | ||
299 | [C(BPU)] = { | ||
300 | [C(OP_READ)] = { | ||
301 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
302 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
303 | }, | ||
304 | [C(OP_WRITE)] = { | ||
305 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
306 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
307 | }, | ||
308 | [C(OP_PREFETCH)] = { | ||
309 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
310 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
311 | }, | ||
312 | }, | ||
313 | }; | ||
314 | |||
315 | static inline unsigned long | ||
316 | armv6_pmcr_read(void) | ||
317 | { | ||
318 | u32 val; | ||
319 | asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val)); | ||
320 | return val; | ||
321 | } | ||
322 | |||
323 | static inline void | ||
324 | armv6_pmcr_write(unsigned long val) | ||
325 | { | ||
326 | asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val)); | ||
327 | } | ||
328 | |||
329 | #define ARMV6_PMCR_ENABLE (1 << 0) | ||
330 | #define ARMV6_PMCR_CTR01_RESET (1 << 1) | ||
331 | #define ARMV6_PMCR_CCOUNT_RESET (1 << 2) | ||
332 | #define ARMV6_PMCR_CCOUNT_DIV (1 << 3) | ||
333 | #define ARMV6_PMCR_COUNT0_IEN (1 << 4) | ||
334 | #define ARMV6_PMCR_COUNT1_IEN (1 << 5) | ||
335 | #define ARMV6_PMCR_CCOUNT_IEN (1 << 6) | ||
336 | #define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8) | ||
337 | #define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9) | ||
338 | #define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10) | ||
339 | #define ARMV6_PMCR_EVT_COUNT0_SHIFT 20 | ||
340 | #define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT) | ||
341 | #define ARMV6_PMCR_EVT_COUNT1_SHIFT 12 | ||
342 | #define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT) | ||
343 | |||
344 | #define ARMV6_PMCR_OVERFLOWED_MASK \ | ||
345 | (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \ | ||
346 | ARMV6_PMCR_CCOUNT_OVERFLOW) | ||
347 | |||
348 | static inline int | ||
349 | armv6_pmcr_has_overflowed(unsigned long pmcr) | ||
350 | { | ||
351 | return pmcr & ARMV6_PMCR_OVERFLOWED_MASK; | ||
352 | } | ||
353 | |||
354 | static inline int | ||
355 | armv6_pmcr_counter_has_overflowed(unsigned long pmcr, | ||
356 | enum armv6_counters counter) | ||
357 | { | ||
358 | int ret = 0; | ||
359 | |||
360 | if (ARMV6_CYCLE_COUNTER == counter) | ||
361 | ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW; | ||
362 | else if (ARMV6_COUNTER0 == counter) | ||
363 | ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW; | ||
364 | else if (ARMV6_COUNTER1 == counter) | ||
365 | ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW; | ||
366 | else | ||
367 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
368 | |||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | static inline u32 | ||
373 | armv6pmu_read_counter(int counter) | ||
374 | { | ||
375 | unsigned long value = 0; | ||
376 | |||
377 | if (ARMV6_CYCLE_COUNTER == counter) | ||
378 | asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value)); | ||
379 | else if (ARMV6_COUNTER0 == counter) | ||
380 | asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value)); | ||
381 | else if (ARMV6_COUNTER1 == counter) | ||
382 | asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value)); | ||
383 | else | ||
384 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
385 | |||
386 | return value; | ||
387 | } | ||
388 | |||
389 | static inline void | ||
390 | armv6pmu_write_counter(int counter, | ||
391 | u32 value) | ||
392 | { | ||
393 | if (ARMV6_CYCLE_COUNTER == counter) | ||
394 | asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value)); | ||
395 | else if (ARMV6_COUNTER0 == counter) | ||
396 | asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value)); | ||
397 | else if (ARMV6_COUNTER1 == counter) | ||
398 | asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value)); | ||
399 | else | ||
400 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
401 | } | ||
402 | |||
403 | static void | ||
404 | armv6pmu_enable_event(struct hw_perf_event *hwc, | ||
405 | int idx) | ||
406 | { | ||
407 | unsigned long val, mask, evt, flags; | ||
408 | |||
409 | if (ARMV6_CYCLE_COUNTER == idx) { | ||
410 | mask = 0; | ||
411 | evt = ARMV6_PMCR_CCOUNT_IEN; | ||
412 | } else if (ARMV6_COUNTER0 == idx) { | ||
413 | mask = ARMV6_PMCR_EVT_COUNT0_MASK; | ||
414 | evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) | | ||
415 | ARMV6_PMCR_COUNT0_IEN; | ||
416 | } else if (ARMV6_COUNTER1 == idx) { | ||
417 | mask = ARMV6_PMCR_EVT_COUNT1_MASK; | ||
418 | evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) | | ||
419 | ARMV6_PMCR_COUNT1_IEN; | ||
420 | } else { | ||
421 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
422 | return; | ||
423 | } | ||
424 | |||
425 | /* | ||
426 | * Mask out the current event and set the counter to count the event | ||
427 | * that we're interested in. | ||
428 | */ | ||
429 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
430 | val = armv6_pmcr_read(); | ||
431 | val &= ~mask; | ||
432 | val |= evt; | ||
433 | armv6_pmcr_write(val); | ||
434 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
435 | } | ||
436 | |||
437 | static irqreturn_t | ||
438 | armv6pmu_handle_irq(int irq_num, | ||
439 | void *dev) | ||
440 | { | ||
441 | unsigned long pmcr = armv6_pmcr_read(); | ||
442 | struct perf_sample_data data; | ||
443 | struct cpu_hw_events *cpuc; | ||
444 | struct pt_regs *regs; | ||
445 | int idx; | ||
446 | |||
447 | if (!armv6_pmcr_has_overflowed(pmcr)) | ||
448 | return IRQ_NONE; | ||
449 | |||
450 | regs = get_irq_regs(); | ||
451 | |||
452 | /* | ||
453 | * The interrupts are cleared by writing the overflow flags back to | ||
454 | * the control register. All of the other bits don't have any effect | ||
455 | * if they are rewritten, so write the whole value back. | ||
456 | */ | ||
457 | armv6_pmcr_write(pmcr); | ||
458 | |||
459 | perf_sample_data_init(&data, 0); | ||
460 | |||
461 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
462 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
463 | struct perf_event *event = cpuc->events[idx]; | ||
464 | struct hw_perf_event *hwc; | ||
465 | |||
466 | if (!test_bit(idx, cpuc->active_mask)) | ||
467 | continue; | ||
468 | |||
469 | /* | ||
470 | * We have a single interrupt for all counters. Check that | ||
471 | * each counter has overflowed before we process it. | ||
472 | */ | ||
473 | if (!armv6_pmcr_counter_has_overflowed(pmcr, idx)) | ||
474 | continue; | ||
475 | |||
476 | hwc = &event->hw; | ||
477 | armpmu_event_update(event, hwc, idx); | ||
478 | data.period = event->hw.last_period; | ||
479 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
480 | continue; | ||
481 | |||
482 | if (perf_event_overflow(event, 0, &data, regs)) | ||
483 | armpmu->disable(hwc, idx); | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * Handle the pending perf events. | ||
488 | * | ||
489 | * Note: this call *must* be run with interrupts disabled. For | ||
490 | * platforms that can have the PMU interrupts raised as an NMI, this | ||
491 | * will not work. | ||
492 | */ | ||
493 | irq_work_run(); | ||
494 | |||
495 | return IRQ_HANDLED; | ||
496 | } | ||
497 | |||
498 | static void | ||
499 | armv6pmu_start(void) | ||
500 | { | ||
501 | unsigned long flags, val; | ||
502 | |||
503 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
504 | val = armv6_pmcr_read(); | ||
505 | val |= ARMV6_PMCR_ENABLE; | ||
506 | armv6_pmcr_write(val); | ||
507 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
508 | } | ||
509 | |||
510 | static void | ||
511 | armv6pmu_stop(void) | ||
512 | { | ||
513 | unsigned long flags, val; | ||
514 | |||
515 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
516 | val = armv6_pmcr_read(); | ||
517 | val &= ~ARMV6_PMCR_ENABLE; | ||
518 | armv6_pmcr_write(val); | ||
519 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
520 | } | ||
521 | |||
522 | static int | ||
523 | armv6pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
524 | struct hw_perf_event *event) | ||
525 | { | ||
526 | /* Always place a cycle counter into the cycle counter. */ | ||
527 | if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) { | ||
528 | if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask)) | ||
529 | return -EAGAIN; | ||
530 | |||
531 | return ARMV6_CYCLE_COUNTER; | ||
532 | } else { | ||
533 | /* | ||
534 | * For anything other than a cycle counter, try and use | ||
535 | * counter0 and counter1. | ||
536 | */ | ||
537 | if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask)) | ||
538 | return ARMV6_COUNTER1; | ||
539 | |||
540 | if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask)) | ||
541 | return ARMV6_COUNTER0; | ||
542 | |||
543 | /* The counters are all in use. */ | ||
544 | return -EAGAIN; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | static void | ||
549 | armv6pmu_disable_event(struct hw_perf_event *hwc, | ||
550 | int idx) | ||
551 | { | ||
552 | unsigned long val, mask, evt, flags; | ||
553 | |||
554 | if (ARMV6_CYCLE_COUNTER == idx) { | ||
555 | mask = ARMV6_PMCR_CCOUNT_IEN; | ||
556 | evt = 0; | ||
557 | } else if (ARMV6_COUNTER0 == idx) { | ||
558 | mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK; | ||
559 | evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT; | ||
560 | } else if (ARMV6_COUNTER1 == idx) { | ||
561 | mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK; | ||
562 | evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT; | ||
563 | } else { | ||
564 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
565 | return; | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * Mask out the current event and set the counter to count the number | ||
570 | * of ETM bus signal assertion cycles. The external reporting should | ||
571 | * be disabled and so this should never increment. | ||
572 | */ | ||
573 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
574 | val = armv6_pmcr_read(); | ||
575 | val &= ~mask; | ||
576 | val |= evt; | ||
577 | armv6_pmcr_write(val); | ||
578 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
579 | } | ||
580 | |||
581 | static void | ||
582 | armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, | ||
583 | int idx) | ||
584 | { | ||
585 | unsigned long val, mask, flags, evt = 0; | ||
586 | |||
587 | if (ARMV6_CYCLE_COUNTER == idx) { | ||
588 | mask = ARMV6_PMCR_CCOUNT_IEN; | ||
589 | } else if (ARMV6_COUNTER0 == idx) { | ||
590 | mask = ARMV6_PMCR_COUNT0_IEN; | ||
591 | } else if (ARMV6_COUNTER1 == idx) { | ||
592 | mask = ARMV6_PMCR_COUNT1_IEN; | ||
593 | } else { | ||
594 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
595 | return; | ||
596 | } | ||
597 | |||
598 | /* | ||
599 | * Unlike UP ARMv6, we don't have a way of stopping the counters. We | ||
600 | * simply disable the interrupt reporting. | ||
601 | */ | ||
602 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
603 | val = armv6_pmcr_read(); | ||
604 | val &= ~mask; | ||
605 | val |= evt; | ||
606 | armv6_pmcr_write(val); | ||
607 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
608 | } | ||
609 | |||
610 | static const struct arm_pmu armv6pmu = { | ||
611 | .id = ARM_PERF_PMU_ID_V6, | ||
612 | .name = "v6", | ||
613 | .handle_irq = armv6pmu_handle_irq, | ||
614 | .enable = armv6pmu_enable_event, | ||
615 | .disable = armv6pmu_disable_event, | ||
616 | .read_counter = armv6pmu_read_counter, | ||
617 | .write_counter = armv6pmu_write_counter, | ||
618 | .get_event_idx = armv6pmu_get_event_idx, | ||
619 | .start = armv6pmu_start, | ||
620 | .stop = armv6pmu_stop, | ||
621 | .cache_map = &armv6_perf_cache_map, | ||
622 | .event_map = &armv6_perf_map, | ||
623 | .raw_event_mask = 0xFF, | ||
624 | .num_events = 3, | ||
625 | .max_period = (1LLU << 32) - 1, | ||
626 | }; | ||
627 | |||
628 | static const struct arm_pmu *__init armv6pmu_init(void) | ||
629 | { | ||
630 | return &armv6pmu; | ||
631 | } | ||
632 | |||
633 | /* | ||
634 | * ARMv6mpcore is almost identical to single core ARMv6 with the exception | ||
635 | * that some of the events have different enumerations and that there is no | ||
636 | * *hack* to stop the programmable counters. To stop the counters we simply | ||
637 | * disable the interrupt reporting and update the event. When unthrottling we | ||
638 | * reset the period and enable the interrupt reporting. | ||
639 | */ | ||
640 | static const struct arm_pmu armv6mpcore_pmu = { | ||
641 | .id = ARM_PERF_PMU_ID_V6MP, | ||
642 | .name = "v6mpcore", | ||
643 | .handle_irq = armv6pmu_handle_irq, | ||
644 | .enable = armv6pmu_enable_event, | ||
645 | .disable = armv6mpcore_pmu_disable_event, | ||
646 | .read_counter = armv6pmu_read_counter, | ||
647 | .write_counter = armv6pmu_write_counter, | ||
648 | .get_event_idx = armv6pmu_get_event_idx, | ||
649 | .start = armv6pmu_start, | ||
650 | .stop = armv6pmu_stop, | ||
651 | .cache_map = &armv6mpcore_perf_cache_map, | ||
652 | .event_map = &armv6mpcore_perf_map, | ||
653 | .raw_event_mask = 0xFF, | ||
654 | .num_events = 3, | ||
655 | .max_period = (1LLU << 32) - 1, | ||
656 | }; | ||
657 | |||
658 | static const struct arm_pmu *__init armv6mpcore_pmu_init(void) | ||
659 | { | ||
660 | return &armv6mpcore_pmu; | ||
661 | } | ||
662 | #else | ||
663 | static const struct arm_pmu *__init armv6pmu_init(void) | ||
664 | { | ||
665 | return NULL; | ||
666 | } | ||
667 | |||
668 | static const struct arm_pmu *__init armv6mpcore_pmu_init(void) | ||
669 | { | ||
670 | return NULL; | ||
671 | } | ||
672 | #endif /* CONFIG_CPU_V6 */ | ||
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c new file mode 100644 index 000000000000..2e1402556fa0 --- /dev/null +++ b/arch/arm/kernel/perf_event_v7.c | |||
@@ -0,0 +1,906 @@ | |||
1 | /* | ||
2 | * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code. | ||
3 | * | ||
4 | * ARMv7 support: Jean Pihet <jpihet@mvista.com> | ||
5 | * 2010 (c) MontaVista Software, LLC. | ||
6 | * | ||
7 | * Copied from ARMv6 code, with the low level code inspired | ||
8 | * by the ARMv7 Oprofile code. | ||
9 | * | ||
10 | * Cortex-A8 has up to 4 configurable performance counters and | ||
11 | * a single cycle counter. | ||
12 | * Cortex-A9 has up to 31 configurable performance counters and | ||
13 | * a single cycle counter. | ||
14 | * | ||
15 | * All counters can be enabled/disabled and IRQ masked separately. The cycle | ||
16 | * counter and all 4 performance counters together can be reset separately. | ||
17 | */ | ||
18 | |||
19 | #ifdef CONFIG_CPU_V7 | ||
20 | /* Common ARMv7 event types */ | ||
21 | enum armv7_perf_types { | ||
22 | ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, | ||
23 | ARMV7_PERFCTR_IFETCH_MISS = 0x01, | ||
24 | ARMV7_PERFCTR_ITLB_MISS = 0x02, | ||
25 | ARMV7_PERFCTR_DCACHE_REFILL = 0x03, | ||
26 | ARMV7_PERFCTR_DCACHE_ACCESS = 0x04, | ||
27 | ARMV7_PERFCTR_DTLB_REFILL = 0x05, | ||
28 | ARMV7_PERFCTR_DREAD = 0x06, | ||
29 | ARMV7_PERFCTR_DWRITE = 0x07, | ||
30 | |||
31 | ARMV7_PERFCTR_EXC_TAKEN = 0x09, | ||
32 | ARMV7_PERFCTR_EXC_EXECUTED = 0x0A, | ||
33 | ARMV7_PERFCTR_CID_WRITE = 0x0B, | ||
34 | /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS. | ||
35 | * It counts: | ||
36 | * - all branch instructions, | ||
37 | * - instructions that explicitly write the PC, | ||
38 | * - exception generating instructions. | ||
39 | */ | ||
40 | ARMV7_PERFCTR_PC_WRITE = 0x0C, | ||
41 | ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D, | ||
42 | ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F, | ||
43 | ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10, | ||
44 | ARMV7_PERFCTR_CLOCK_CYCLES = 0x11, | ||
45 | |||
46 | ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12, | ||
47 | |||
48 | ARMV7_PERFCTR_CPU_CYCLES = 0xFF | ||
49 | }; | ||
50 | |||
51 | /* ARMv7 Cortex-A8 specific event types */ | ||
52 | enum armv7_a8_perf_types { | ||
53 | ARMV7_PERFCTR_INSTR_EXECUTED = 0x08, | ||
54 | |||
55 | ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E, | ||
56 | |||
57 | ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40, | ||
58 | ARMV7_PERFCTR_L2_STORE_MERGED = 0x41, | ||
59 | ARMV7_PERFCTR_L2_STORE_BUFF = 0x42, | ||
60 | ARMV7_PERFCTR_L2_ACCESS = 0x43, | ||
61 | ARMV7_PERFCTR_L2_CACH_MISS = 0x44, | ||
62 | ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45, | ||
63 | ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46, | ||
64 | ARMV7_PERFCTR_MEMORY_REPLAY = 0x47, | ||
65 | ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48, | ||
66 | ARMV7_PERFCTR_L1_DATA_MISS = 0x49, | ||
67 | ARMV7_PERFCTR_L1_INST_MISS = 0x4A, | ||
68 | ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B, | ||
69 | ARMV7_PERFCTR_L1_NEON_DATA = 0x4C, | ||
70 | ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D, | ||
71 | ARMV7_PERFCTR_L2_NEON = 0x4E, | ||
72 | ARMV7_PERFCTR_L2_NEON_HIT = 0x4F, | ||
73 | ARMV7_PERFCTR_L1_INST = 0x50, | ||
74 | ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51, | ||
75 | ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52, | ||
76 | ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53, | ||
77 | ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54, | ||
78 | ARMV7_PERFCTR_OP_EXECUTED = 0x55, | ||
79 | ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56, | ||
80 | ARMV7_PERFCTR_CYCLES_INST = 0x57, | ||
81 | ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58, | ||
82 | ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59, | ||
83 | ARMV7_PERFCTR_NEON_CYCLES = 0x5A, | ||
84 | |||
85 | ARMV7_PERFCTR_PMU0_EVENTS = 0x70, | ||
86 | ARMV7_PERFCTR_PMU1_EVENTS = 0x71, | ||
87 | ARMV7_PERFCTR_PMU_EVENTS = 0x72, | ||
88 | }; | ||
89 | |||
90 | /* ARMv7 Cortex-A9 specific event types */ | ||
91 | enum armv7_a9_perf_types { | ||
92 | ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40, | ||
93 | ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41, | ||
94 | ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42, | ||
95 | |||
96 | ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50, | ||
97 | ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51, | ||
98 | |||
99 | ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60, | ||
100 | ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61, | ||
101 | ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62, | ||
102 | ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63, | ||
103 | ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64, | ||
104 | ARMV7_PERFCTR_DATA_EVICTION = 0x65, | ||
105 | ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66, | ||
106 | ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67, | ||
107 | ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68, | ||
108 | |||
109 | ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E, | ||
110 | |||
111 | ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70, | ||
112 | ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71, | ||
113 | ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72, | ||
114 | ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73, | ||
115 | ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74, | ||
116 | |||
117 | ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80, | ||
118 | ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81, | ||
119 | ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82, | ||
120 | ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83, | ||
121 | ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84, | ||
122 | ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85, | ||
123 | ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86, | ||
124 | |||
125 | ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A, | ||
126 | ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B, | ||
127 | |||
128 | ARMV7_PERFCTR_ISB_INST = 0x90, | ||
129 | ARMV7_PERFCTR_DSB_INST = 0x91, | ||
130 | ARMV7_PERFCTR_DMB_INST = 0x92, | ||
131 | ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93, | ||
132 | |||
133 | ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0, | ||
134 | ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1, | ||
135 | ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2, | ||
136 | ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3, | ||
137 | ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4, | ||
138 | ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5 | ||
139 | }; | ||
140 | |||
141 | /* | ||
142 | * Cortex-A8 HW events mapping | ||
143 | * | ||
144 | * The hardware events that we support. We do support cache operations but | ||
145 | * we have harvard caches and no way to combine instruction and data | ||
146 | * accesses/misses in hardware. | ||
147 | */ | ||
148 | static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = { | ||
149 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, | ||
150 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, | ||
151 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
152 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
153 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, | ||
154 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
155 | [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, | ||
156 | }; | ||
157 | |||
158 | static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
159 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
160 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
161 | [C(L1D)] = { | ||
162 | /* | ||
163 | * The performance counters don't differentiate between read | ||
164 | * and write accesses/misses so this isn't strictly correct, | ||
165 | * but it's the best we can do. Writes and reads get | ||
166 | * combined. | ||
167 | */ | ||
168 | [C(OP_READ)] = { | ||
169 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
170 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
171 | }, | ||
172 | [C(OP_WRITE)] = { | ||
173 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
174 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
175 | }, | ||
176 | [C(OP_PREFETCH)] = { | ||
177 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
178 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
179 | }, | ||
180 | }, | ||
181 | [C(L1I)] = { | ||
182 | [C(OP_READ)] = { | ||
183 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, | ||
184 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, | ||
185 | }, | ||
186 | [C(OP_WRITE)] = { | ||
187 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, | ||
188 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, | ||
189 | }, | ||
190 | [C(OP_PREFETCH)] = { | ||
191 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
192 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
193 | }, | ||
194 | }, | ||
195 | [C(LL)] = { | ||
196 | [C(OP_READ)] = { | ||
197 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, | ||
198 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, | ||
199 | }, | ||
200 | [C(OP_WRITE)] = { | ||
201 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, | ||
202 | [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, | ||
203 | }, | ||
204 | [C(OP_PREFETCH)] = { | ||
205 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
206 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
207 | }, | ||
208 | }, | ||
209 | [C(DTLB)] = { | ||
210 | /* | ||
211 | * Only ITLB misses and DTLB refills are supported. | ||
212 | * If users want the DTLB refills misses a raw counter | ||
213 | * must be used. | ||
214 | */ | ||
215 | [C(OP_READ)] = { | ||
216 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
217 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
218 | }, | ||
219 | [C(OP_WRITE)] = { | ||
220 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
221 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
222 | }, | ||
223 | [C(OP_PREFETCH)] = { | ||
224 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
225 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
226 | }, | ||
227 | }, | ||
228 | [C(ITLB)] = { | ||
229 | [C(OP_READ)] = { | ||
230 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
231 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
232 | }, | ||
233 | [C(OP_WRITE)] = { | ||
234 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
235 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
236 | }, | ||
237 | [C(OP_PREFETCH)] = { | ||
238 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
239 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
240 | }, | ||
241 | }, | ||
242 | [C(BPU)] = { | ||
243 | [C(OP_READ)] = { | ||
244 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
245 | [C(RESULT_MISS)] | ||
246 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
247 | }, | ||
248 | [C(OP_WRITE)] = { | ||
249 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
250 | [C(RESULT_MISS)] | ||
251 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
252 | }, | ||
253 | [C(OP_PREFETCH)] = { | ||
254 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
255 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
256 | }, | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | /* | ||
261 | * Cortex-A9 HW events mapping | ||
262 | */ | ||
263 | static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = { | ||
264 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, | ||
265 | [PERF_COUNT_HW_INSTRUCTIONS] = | ||
266 | ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE, | ||
267 | [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT, | ||
268 | [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS, | ||
269 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, | ||
270 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
271 | [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, | ||
272 | }; | ||
273 | |||
274 | static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
275 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
276 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
277 | [C(L1D)] = { | ||
278 | /* | ||
279 | * The performance counters don't differentiate between read | ||
280 | * and write accesses/misses so this isn't strictly correct, | ||
281 | * but it's the best we can do. Writes and reads get | ||
282 | * combined. | ||
283 | */ | ||
284 | [C(OP_READ)] = { | ||
285 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
286 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
287 | }, | ||
288 | [C(OP_WRITE)] = { | ||
289 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, | ||
290 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, | ||
291 | }, | ||
292 | [C(OP_PREFETCH)] = { | ||
293 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
294 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
295 | }, | ||
296 | }, | ||
297 | [C(L1I)] = { | ||
298 | [C(OP_READ)] = { | ||
299 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
300 | [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, | ||
301 | }, | ||
302 | [C(OP_WRITE)] = { | ||
303 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
304 | [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, | ||
305 | }, | ||
306 | [C(OP_PREFETCH)] = { | ||
307 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
308 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
309 | }, | ||
310 | }, | ||
311 | [C(LL)] = { | ||
312 | [C(OP_READ)] = { | ||
313 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
314 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
315 | }, | ||
316 | [C(OP_WRITE)] = { | ||
317 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
318 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
319 | }, | ||
320 | [C(OP_PREFETCH)] = { | ||
321 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
322 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
323 | }, | ||
324 | }, | ||
325 | [C(DTLB)] = { | ||
326 | /* | ||
327 | * Only ITLB misses and DTLB refills are supported. | ||
328 | * If users want the DTLB refills misses a raw counter | ||
329 | * must be used. | ||
330 | */ | ||
331 | [C(OP_READ)] = { | ||
332 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
333 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
334 | }, | ||
335 | [C(OP_WRITE)] = { | ||
336 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
337 | [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, | ||
338 | }, | ||
339 | [C(OP_PREFETCH)] = { | ||
340 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
341 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
342 | }, | ||
343 | }, | ||
344 | [C(ITLB)] = { | ||
345 | [C(OP_READ)] = { | ||
346 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
347 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
348 | }, | ||
349 | [C(OP_WRITE)] = { | ||
350 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
351 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
352 | }, | ||
353 | [C(OP_PREFETCH)] = { | ||
354 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
355 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
356 | }, | ||
357 | }, | ||
358 | [C(BPU)] = { | ||
359 | [C(OP_READ)] = { | ||
360 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
361 | [C(RESULT_MISS)] | ||
362 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
363 | }, | ||
364 | [C(OP_WRITE)] = { | ||
365 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, | ||
366 | [C(RESULT_MISS)] | ||
367 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
368 | }, | ||
369 | [C(OP_PREFETCH)] = { | ||
370 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
371 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
372 | }, | ||
373 | }, | ||
374 | }; | ||
375 | |||
376 | /* | ||
377 | * Perf Events counters | ||
378 | */ | ||
379 | enum armv7_counters { | ||
380 | ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */ | ||
381 | ARMV7_COUNTER0 = 2, /* First event counter */ | ||
382 | }; | ||
383 | |||
384 | /* | ||
385 | * The cycle counter is ARMV7_CYCLE_COUNTER. | ||
386 | * The first event counter is ARMV7_COUNTER0. | ||
387 | * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1). | ||
388 | */ | ||
389 | #define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1) | ||
390 | |||
391 | /* | ||
392 | * ARMv7 low level PMNC access | ||
393 | */ | ||
394 | |||
395 | /* | ||
396 | * Per-CPU PMNC: config reg | ||
397 | */ | ||
398 | #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */ | ||
399 | #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */ | ||
400 | #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */ | ||
401 | #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */ | ||
402 | #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */ | ||
403 | #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ | ||
404 | #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */ | ||
405 | #define ARMV7_PMNC_N_MASK 0x1f | ||
406 | #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */ | ||
407 | |||
408 | /* | ||
409 | * Available counters | ||
410 | */ | ||
411 | #define ARMV7_CNT0 0 /* First event counter */ | ||
412 | #define ARMV7_CCNT 31 /* Cycle counter */ | ||
413 | |||
414 | /* Perf Event to low level counters mapping */ | ||
415 | #define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0) | ||
416 | |||
417 | /* | ||
418 | * CNTENS: counters enable reg | ||
419 | */ | ||
420 | #define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
421 | #define ARMV7_CNTENS_C (1 << ARMV7_CCNT) | ||
422 | |||
423 | /* | ||
424 | * CNTENC: counters disable reg | ||
425 | */ | ||
426 | #define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
427 | #define ARMV7_CNTENC_C (1 << ARMV7_CCNT) | ||
428 | |||
429 | /* | ||
430 | * INTENS: counters overflow interrupt enable reg | ||
431 | */ | ||
432 | #define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
433 | #define ARMV7_INTENS_C (1 << ARMV7_CCNT) | ||
434 | |||
435 | /* | ||
436 | * INTENC: counters overflow interrupt disable reg | ||
437 | */ | ||
438 | #define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
439 | #define ARMV7_INTENC_C (1 << ARMV7_CCNT) | ||
440 | |||
441 | /* | ||
442 | * EVTSEL: Event selection reg | ||
443 | */ | ||
444 | #define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */ | ||
445 | |||
446 | /* | ||
447 | * SELECT: Counter selection reg | ||
448 | */ | ||
449 | #define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */ | ||
450 | |||
451 | /* | ||
452 | * FLAG: counters overflow flag status reg | ||
453 | */ | ||
454 | #define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) | ||
455 | #define ARMV7_FLAG_C (1 << ARMV7_CCNT) | ||
456 | #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */ | ||
457 | #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK | ||
458 | |||
459 | static inline unsigned long armv7_pmnc_read(void) | ||
460 | { | ||
461 | u32 val; | ||
462 | asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val)); | ||
463 | return val; | ||
464 | } | ||
465 | |||
466 | static inline void armv7_pmnc_write(unsigned long val) | ||
467 | { | ||
468 | val &= ARMV7_PMNC_MASK; | ||
469 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); | ||
470 | } | ||
471 | |||
472 | static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) | ||
473 | { | ||
474 | return pmnc & ARMV7_OVERFLOWED_MASK; | ||
475 | } | ||
476 | |||
477 | static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, | ||
478 | enum armv7_counters counter) | ||
479 | { | ||
480 | int ret = 0; | ||
481 | |||
482 | if (counter == ARMV7_CYCLE_COUNTER) | ||
483 | ret = pmnc & ARMV7_FLAG_C; | ||
484 | else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST)) | ||
485 | ret = pmnc & ARMV7_FLAG_P(counter); | ||
486 | else | ||
487 | pr_err("CPU%u checking wrong counter %d overflow status\n", | ||
488 | smp_processor_id(), counter); | ||
489 | |||
490 | return ret; | ||
491 | } | ||
492 | |||
493 | static inline int armv7_pmnc_select_counter(unsigned int idx) | ||
494 | { | ||
495 | u32 val; | ||
496 | |||
497 | if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) { | ||
498 | pr_err("CPU%u selecting wrong PMNC counter" | ||
499 | " %d\n", smp_processor_id(), idx); | ||
500 | return -1; | ||
501 | } | ||
502 | |||
503 | val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; | ||
504 | asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); | ||
505 | |||
506 | return idx; | ||
507 | } | ||
508 | |||
509 | static inline u32 armv7pmu_read_counter(int idx) | ||
510 | { | ||
511 | unsigned long value = 0; | ||
512 | |||
513 | if (idx == ARMV7_CYCLE_COUNTER) | ||
514 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); | ||
515 | else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { | ||
516 | if (armv7_pmnc_select_counter(idx) == idx) | ||
517 | asm volatile("mrc p15, 0, %0, c9, c13, 2" | ||
518 | : "=r" (value)); | ||
519 | } else | ||
520 | pr_err("CPU%u reading wrong counter %d\n", | ||
521 | smp_processor_id(), idx); | ||
522 | |||
523 | return value; | ||
524 | } | ||
525 | |||
526 | static inline void armv7pmu_write_counter(int idx, u32 value) | ||
527 | { | ||
528 | if (idx == ARMV7_CYCLE_COUNTER) | ||
529 | asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); | ||
530 | else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { | ||
531 | if (armv7_pmnc_select_counter(idx) == idx) | ||
532 | asm volatile("mcr p15, 0, %0, c9, c13, 2" | ||
533 | : : "r" (value)); | ||
534 | } else | ||
535 | pr_err("CPU%u writing wrong counter %d\n", | ||
536 | smp_processor_id(), idx); | ||
537 | } | ||
538 | |||
539 | static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val) | ||
540 | { | ||
541 | if (armv7_pmnc_select_counter(idx) == idx) { | ||
542 | val &= ARMV7_EVTSEL_MASK; | ||
543 | asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); | ||
544 | } | ||
545 | } | ||
546 | |||
547 | static inline u32 armv7_pmnc_enable_counter(unsigned int idx) | ||
548 | { | ||
549 | u32 val; | ||
550 | |||
551 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
552 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
553 | pr_err("CPU%u enabling wrong PMNC counter" | ||
554 | " %d\n", smp_processor_id(), idx); | ||
555 | return -1; | ||
556 | } | ||
557 | |||
558 | if (idx == ARMV7_CYCLE_COUNTER) | ||
559 | val = ARMV7_CNTENS_C; | ||
560 | else | ||
561 | val = ARMV7_CNTENS_P(idx); | ||
562 | |||
563 | asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); | ||
564 | |||
565 | return idx; | ||
566 | } | ||
567 | |||
568 | static inline u32 armv7_pmnc_disable_counter(unsigned int idx) | ||
569 | { | ||
570 | u32 val; | ||
571 | |||
572 | |||
573 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
574 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
575 | pr_err("CPU%u disabling wrong PMNC counter" | ||
576 | " %d\n", smp_processor_id(), idx); | ||
577 | return -1; | ||
578 | } | ||
579 | |||
580 | if (idx == ARMV7_CYCLE_COUNTER) | ||
581 | val = ARMV7_CNTENC_C; | ||
582 | else | ||
583 | val = ARMV7_CNTENC_P(idx); | ||
584 | |||
585 | asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); | ||
586 | |||
587 | return idx; | ||
588 | } | ||
589 | |||
590 | static inline u32 armv7_pmnc_enable_intens(unsigned int idx) | ||
591 | { | ||
592 | u32 val; | ||
593 | |||
594 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
595 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
596 | pr_err("CPU%u enabling wrong PMNC counter" | ||
597 | " interrupt enable %d\n", smp_processor_id(), idx); | ||
598 | return -1; | ||
599 | } | ||
600 | |||
601 | if (idx == ARMV7_CYCLE_COUNTER) | ||
602 | val = ARMV7_INTENS_C; | ||
603 | else | ||
604 | val = ARMV7_INTENS_P(idx); | ||
605 | |||
606 | asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val)); | ||
607 | |||
608 | return idx; | ||
609 | } | ||
610 | |||
611 | static inline u32 armv7_pmnc_disable_intens(unsigned int idx) | ||
612 | { | ||
613 | u32 val; | ||
614 | |||
615 | if ((idx != ARMV7_CYCLE_COUNTER) && | ||
616 | ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { | ||
617 | pr_err("CPU%u disabling wrong PMNC counter" | ||
618 | " interrupt enable %d\n", smp_processor_id(), idx); | ||
619 | return -1; | ||
620 | } | ||
621 | |||
622 | if (idx == ARMV7_CYCLE_COUNTER) | ||
623 | val = ARMV7_INTENC_C; | ||
624 | else | ||
625 | val = ARMV7_INTENC_P(idx); | ||
626 | |||
627 | asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val)); | ||
628 | |||
629 | return idx; | ||
630 | } | ||
631 | |||
632 | static inline u32 armv7_pmnc_getreset_flags(void) | ||
633 | { | ||
634 | u32 val; | ||
635 | |||
636 | /* Read */ | ||
637 | asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); | ||
638 | |||
639 | /* Write to clear flags */ | ||
640 | val &= ARMV7_FLAG_MASK; | ||
641 | asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val)); | ||
642 | |||
643 | return val; | ||
644 | } | ||
645 | |||
646 | #ifdef DEBUG | ||
647 | static void armv7_pmnc_dump_regs(void) | ||
648 | { | ||
649 | u32 val; | ||
650 | unsigned int cnt; | ||
651 | |||
652 | printk(KERN_INFO "PMNC registers dump:\n"); | ||
653 | |||
654 | asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); | ||
655 | printk(KERN_INFO "PMNC =0x%08x\n", val); | ||
656 | |||
657 | asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val)); | ||
658 | printk(KERN_INFO "CNTENS=0x%08x\n", val); | ||
659 | |||
660 | asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val)); | ||
661 | printk(KERN_INFO "INTENS=0x%08x\n", val); | ||
662 | |||
663 | asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val)); | ||
664 | printk(KERN_INFO "FLAGS =0x%08x\n", val); | ||
665 | |||
666 | asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val)); | ||
667 | printk(KERN_INFO "SELECT=0x%08x\n", val); | ||
668 | |||
669 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); | ||
670 | printk(KERN_INFO "CCNT =0x%08x\n", val); | ||
671 | |||
672 | for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) { | ||
673 | armv7_pmnc_select_counter(cnt); | ||
674 | asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); | ||
675 | printk(KERN_INFO "CNT[%d] count =0x%08x\n", | ||
676 | cnt-ARMV7_EVENT_CNT_TO_CNTx, val); | ||
677 | asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); | ||
678 | printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", | ||
679 | cnt-ARMV7_EVENT_CNT_TO_CNTx, val); | ||
680 | } | ||
681 | } | ||
682 | #endif | ||
683 | |||
684 | static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx) | ||
685 | { | ||
686 | unsigned long flags; | ||
687 | |||
688 | /* | ||
689 | * Enable counter and interrupt, and set the counter to count | ||
690 | * the event that we're interested in. | ||
691 | */ | ||
692 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
693 | |||
694 | /* | ||
695 | * Disable counter | ||
696 | */ | ||
697 | armv7_pmnc_disable_counter(idx); | ||
698 | |||
699 | /* | ||
700 | * Set event (if destined for PMNx counters) | ||
701 | * We don't need to set the event if it's a cycle count | ||
702 | */ | ||
703 | if (idx != ARMV7_CYCLE_COUNTER) | ||
704 | armv7_pmnc_write_evtsel(idx, hwc->config_base); | ||
705 | |||
706 | /* | ||
707 | * Enable interrupt for this counter | ||
708 | */ | ||
709 | armv7_pmnc_enable_intens(idx); | ||
710 | |||
711 | /* | ||
712 | * Enable counter | ||
713 | */ | ||
714 | armv7_pmnc_enable_counter(idx); | ||
715 | |||
716 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
717 | } | ||
718 | |||
719 | static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx) | ||
720 | { | ||
721 | unsigned long flags; | ||
722 | |||
723 | /* | ||
724 | * Disable counter and interrupt | ||
725 | */ | ||
726 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
727 | |||
728 | /* | ||
729 | * Disable counter | ||
730 | */ | ||
731 | armv7_pmnc_disable_counter(idx); | ||
732 | |||
733 | /* | ||
734 | * Disable interrupt for this counter | ||
735 | */ | ||
736 | armv7_pmnc_disable_intens(idx); | ||
737 | |||
738 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
739 | } | ||
740 | |||
741 | static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | ||
742 | { | ||
743 | unsigned long pmnc; | ||
744 | struct perf_sample_data data; | ||
745 | struct cpu_hw_events *cpuc; | ||
746 | struct pt_regs *regs; | ||
747 | int idx; | ||
748 | |||
749 | /* | ||
750 | * Get and reset the IRQ flags | ||
751 | */ | ||
752 | pmnc = armv7_pmnc_getreset_flags(); | ||
753 | |||
754 | /* | ||
755 | * Did an overflow occur? | ||
756 | */ | ||
757 | if (!armv7_pmnc_has_overflowed(pmnc)) | ||
758 | return IRQ_NONE; | ||
759 | |||
760 | /* | ||
761 | * Handle the counter(s) overflow(s) | ||
762 | */ | ||
763 | regs = get_irq_regs(); | ||
764 | |||
765 | perf_sample_data_init(&data, 0); | ||
766 | |||
767 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
768 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
769 | struct perf_event *event = cpuc->events[idx]; | ||
770 | struct hw_perf_event *hwc; | ||
771 | |||
772 | if (!test_bit(idx, cpuc->active_mask)) | ||
773 | continue; | ||
774 | |||
775 | /* | ||
776 | * We have a single interrupt for all counters. Check that | ||
777 | * each counter has overflowed before we process it. | ||
778 | */ | ||
779 | if (!armv7_pmnc_counter_has_overflowed(pmnc, idx)) | ||
780 | continue; | ||
781 | |||
782 | hwc = &event->hw; | ||
783 | armpmu_event_update(event, hwc, idx); | ||
784 | data.period = event->hw.last_period; | ||
785 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
786 | continue; | ||
787 | |||
788 | if (perf_event_overflow(event, 0, &data, regs)) | ||
789 | armpmu->disable(hwc, idx); | ||
790 | } | ||
791 | |||
792 | /* | ||
793 | * Handle the pending perf events. | ||
794 | * | ||
795 | * Note: this call *must* be run with interrupts disabled. For | ||
796 | * platforms that can have the PMU interrupts raised as an NMI, this | ||
797 | * will not work. | ||
798 | */ | ||
799 | irq_work_run(); | ||
800 | |||
801 | return IRQ_HANDLED; | ||
802 | } | ||
803 | |||
804 | static void armv7pmu_start(void) | ||
805 | { | ||
806 | unsigned long flags; | ||
807 | |||
808 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
809 | /* Enable all counters */ | ||
810 | armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); | ||
811 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
812 | } | ||
813 | |||
814 | static void armv7pmu_stop(void) | ||
815 | { | ||
816 | unsigned long flags; | ||
817 | |||
818 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
819 | /* Disable all counters */ | ||
820 | armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); | ||
821 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
822 | } | ||
823 | |||
824 | static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
825 | struct hw_perf_event *event) | ||
826 | { | ||
827 | int idx; | ||
828 | |||
829 | /* Always place a cycle counter into the cycle counter. */ | ||
830 | if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) { | ||
831 | if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask)) | ||
832 | return -EAGAIN; | ||
833 | |||
834 | return ARMV7_CYCLE_COUNTER; | ||
835 | } else { | ||
836 | /* | ||
837 | * For anything other than a cycle counter, try and use | ||
838 | * the events counters | ||
839 | */ | ||
840 | for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) { | ||
841 | if (!test_and_set_bit(idx, cpuc->used_mask)) | ||
842 | return idx; | ||
843 | } | ||
844 | |||
845 | /* The counters are all in use. */ | ||
846 | return -EAGAIN; | ||
847 | } | ||
848 | } | ||
849 | |||
850 | static struct arm_pmu armv7pmu = { | ||
851 | .handle_irq = armv7pmu_handle_irq, | ||
852 | .enable = armv7pmu_enable_event, | ||
853 | .disable = armv7pmu_disable_event, | ||
854 | .read_counter = armv7pmu_read_counter, | ||
855 | .write_counter = armv7pmu_write_counter, | ||
856 | .get_event_idx = armv7pmu_get_event_idx, | ||
857 | .start = armv7pmu_start, | ||
858 | .stop = armv7pmu_stop, | ||
859 | .raw_event_mask = 0xFF, | ||
860 | .max_period = (1LLU << 32) - 1, | ||
861 | }; | ||
862 | |||
863 | static u32 __init armv7_reset_read_pmnc(void) | ||
864 | { | ||
865 | u32 nb_cnt; | ||
866 | |||
867 | /* Initialize & Reset PMNC: C and P bits */ | ||
868 | armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); | ||
869 | |||
870 | /* Read the nb of CNTx counters supported from PMNC */ | ||
871 | nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; | ||
872 | |||
873 | /* Add the CPU cycles counter and return */ | ||
874 | return nb_cnt + 1; | ||
875 | } | ||
876 | |||
877 | static const struct arm_pmu *__init armv7_a8_pmu_init(void) | ||
878 | { | ||
879 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; | ||
880 | armv7pmu.name = "ARMv7 Cortex-A8"; | ||
881 | armv7pmu.cache_map = &armv7_a8_perf_cache_map; | ||
882 | armv7pmu.event_map = &armv7_a8_perf_map; | ||
883 | armv7pmu.num_events = armv7_reset_read_pmnc(); | ||
884 | return &armv7pmu; | ||
885 | } | ||
886 | |||
887 | static const struct arm_pmu *__init armv7_a9_pmu_init(void) | ||
888 | { | ||
889 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; | ||
890 | armv7pmu.name = "ARMv7 Cortex-A9"; | ||
891 | armv7pmu.cache_map = &armv7_a9_perf_cache_map; | ||
892 | armv7pmu.event_map = &armv7_a9_perf_map; | ||
893 | armv7pmu.num_events = armv7_reset_read_pmnc(); | ||
894 | return &armv7pmu; | ||
895 | } | ||
896 | #else | ||
897 | static const struct arm_pmu *__init armv7_a8_pmu_init(void) | ||
898 | { | ||
899 | return NULL; | ||
900 | } | ||
901 | |||
902 | static const struct arm_pmu *__init armv7_a9_pmu_init(void) | ||
903 | { | ||
904 | return NULL; | ||
905 | } | ||
906 | #endif /* CONFIG_CPU_V7 */ | ||
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c new file mode 100644 index 000000000000..28cd3b025bc3 --- /dev/null +++ b/arch/arm/kernel/perf_event_xscale.c | |||
@@ -0,0 +1,807 @@ | |||
1 | /* | ||
2 | * ARMv5 [xscale] Performance counter handling code. | ||
3 | * | ||
4 | * Copyright (C) 2010, ARM Ltd., Will Deacon <will.deacon@arm.com> | ||
5 | * | ||
6 | * Based on the previous xscale OProfile code. | ||
7 | * | ||
8 | * There are two variants of the xscale PMU that we support: | ||
9 | * - xscale1pmu: 2 event counters and a cycle counter | ||
10 | * - xscale2pmu: 4 event counters and a cycle counter | ||
11 | * The two variants share event definitions, but have different | ||
12 | * PMU structures. | ||
13 | */ | ||
14 | |||
15 | #ifdef CONFIG_CPU_XSCALE | ||
16 | enum xscale_perf_types { | ||
17 | XSCALE_PERFCTR_ICACHE_MISS = 0x00, | ||
18 | XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01, | ||
19 | XSCALE_PERFCTR_DATA_STALL = 0x02, | ||
20 | XSCALE_PERFCTR_ITLB_MISS = 0x03, | ||
21 | XSCALE_PERFCTR_DTLB_MISS = 0x04, | ||
22 | XSCALE_PERFCTR_BRANCH = 0x05, | ||
23 | XSCALE_PERFCTR_BRANCH_MISS = 0x06, | ||
24 | XSCALE_PERFCTR_INSTRUCTION = 0x07, | ||
25 | XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08, | ||
26 | XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09, | ||
27 | XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A, | ||
28 | XSCALE_PERFCTR_DCACHE_MISS = 0x0B, | ||
29 | XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C, | ||
30 | XSCALE_PERFCTR_PC_CHANGED = 0x0D, | ||
31 | XSCALE_PERFCTR_BCU_REQUEST = 0x10, | ||
32 | XSCALE_PERFCTR_BCU_FULL = 0x11, | ||
33 | XSCALE_PERFCTR_BCU_DRAIN = 0x12, | ||
34 | XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14, | ||
35 | XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15, | ||
36 | XSCALE_PERFCTR_RMW = 0x16, | ||
37 | /* XSCALE_PERFCTR_CCNT is not hardware defined */ | ||
38 | XSCALE_PERFCTR_CCNT = 0xFE, | ||
39 | XSCALE_PERFCTR_UNUSED = 0xFF, | ||
40 | }; | ||
41 | |||
42 | enum xscale_counters { | ||
43 | XSCALE_CYCLE_COUNTER = 1, | ||
44 | XSCALE_COUNTER0, | ||
45 | XSCALE_COUNTER1, | ||
46 | XSCALE_COUNTER2, | ||
47 | XSCALE_COUNTER3, | ||
48 | }; | ||
49 | |||
50 | static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = { | ||
51 | [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT, | ||
52 | [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION, | ||
53 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
54 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
55 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH, | ||
56 | [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS, | ||
57 | [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, | ||
58 | }; | ||
59 | |||
60 | static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
61 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
62 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
63 | [C(L1D)] = { | ||
64 | [C(OP_READ)] = { | ||
65 | [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, | ||
66 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, | ||
67 | }, | ||
68 | [C(OP_WRITE)] = { | ||
69 | [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, | ||
70 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, | ||
71 | }, | ||
72 | [C(OP_PREFETCH)] = { | ||
73 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
74 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
75 | }, | ||
76 | }, | ||
77 | [C(L1I)] = { | ||
78 | [C(OP_READ)] = { | ||
79 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
80 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, | ||
81 | }, | ||
82 | [C(OP_WRITE)] = { | ||
83 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
84 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, | ||
85 | }, | ||
86 | [C(OP_PREFETCH)] = { | ||
87 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
88 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
89 | }, | ||
90 | }, | ||
91 | [C(LL)] = { | ||
92 | [C(OP_READ)] = { | ||
93 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
94 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
95 | }, | ||
96 | [C(OP_WRITE)] = { | ||
97 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
98 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
99 | }, | ||
100 | [C(OP_PREFETCH)] = { | ||
101 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
102 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
103 | }, | ||
104 | }, | ||
105 | [C(DTLB)] = { | ||
106 | [C(OP_READ)] = { | ||
107 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
108 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, | ||
109 | }, | ||
110 | [C(OP_WRITE)] = { | ||
111 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
112 | [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, | ||
113 | }, | ||
114 | [C(OP_PREFETCH)] = { | ||
115 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
116 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
117 | }, | ||
118 | }, | ||
119 | [C(ITLB)] = { | ||
120 | [C(OP_READ)] = { | ||
121 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
122 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, | ||
123 | }, | ||
124 | [C(OP_WRITE)] = { | ||
125 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
126 | [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, | ||
127 | }, | ||
128 | [C(OP_PREFETCH)] = { | ||
129 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
130 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
131 | }, | ||
132 | }, | ||
133 | [C(BPU)] = { | ||
134 | [C(OP_READ)] = { | ||
135 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
136 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
137 | }, | ||
138 | [C(OP_WRITE)] = { | ||
139 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
140 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
141 | }, | ||
142 | [C(OP_PREFETCH)] = { | ||
143 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
144 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
145 | }, | ||
146 | }, | ||
147 | }; | ||
148 | |||
149 | #define XSCALE_PMU_ENABLE 0x001 | ||
150 | #define XSCALE_PMN_RESET 0x002 | ||
151 | #define XSCALE_CCNT_RESET 0x004 | ||
152 | #define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET) | ||
153 | #define XSCALE_PMU_CNT64 0x008 | ||
154 | |||
155 | #define XSCALE1_OVERFLOWED_MASK 0x700 | ||
156 | #define XSCALE1_CCOUNT_OVERFLOW 0x400 | ||
157 | #define XSCALE1_COUNT0_OVERFLOW 0x100 | ||
158 | #define XSCALE1_COUNT1_OVERFLOW 0x200 | ||
159 | #define XSCALE1_CCOUNT_INT_EN 0x040 | ||
160 | #define XSCALE1_COUNT0_INT_EN 0x010 | ||
161 | #define XSCALE1_COUNT1_INT_EN 0x020 | ||
162 | #define XSCALE1_COUNT0_EVT_SHFT 12 | ||
163 | #define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT) | ||
164 | #define XSCALE1_COUNT1_EVT_SHFT 20 | ||
165 | #define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT) | ||
166 | |||
167 | static inline u32 | ||
168 | xscale1pmu_read_pmnc(void) | ||
169 | { | ||
170 | u32 val; | ||
171 | asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val)); | ||
172 | return val; | ||
173 | } | ||
174 | |||
175 | static inline void | ||
176 | xscale1pmu_write_pmnc(u32 val) | ||
177 | { | ||
178 | /* upper 4bits and 7, 11 are write-as-0 */ | ||
179 | val &= 0xffff77f; | ||
180 | asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val)); | ||
181 | } | ||
182 | |||
183 | static inline int | ||
184 | xscale1_pmnc_counter_has_overflowed(unsigned long pmnc, | ||
185 | enum xscale_counters counter) | ||
186 | { | ||
187 | int ret = 0; | ||
188 | |||
189 | switch (counter) { | ||
190 | case XSCALE_CYCLE_COUNTER: | ||
191 | ret = pmnc & XSCALE1_CCOUNT_OVERFLOW; | ||
192 | break; | ||
193 | case XSCALE_COUNTER0: | ||
194 | ret = pmnc & XSCALE1_COUNT0_OVERFLOW; | ||
195 | break; | ||
196 | case XSCALE_COUNTER1: | ||
197 | ret = pmnc & XSCALE1_COUNT1_OVERFLOW; | ||
198 | break; | ||
199 | default: | ||
200 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
201 | } | ||
202 | |||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | static irqreturn_t | ||
207 | xscale1pmu_handle_irq(int irq_num, void *dev) | ||
208 | { | ||
209 | unsigned long pmnc; | ||
210 | struct perf_sample_data data; | ||
211 | struct cpu_hw_events *cpuc; | ||
212 | struct pt_regs *regs; | ||
213 | int idx; | ||
214 | |||
215 | /* | ||
216 | * NOTE: there's an A stepping erratum that states if an overflow | ||
217 | * bit already exists and another occurs, the previous | ||
218 | * Overflow bit gets cleared. There's no workaround. | ||
219 | * Fixed in B stepping or later. | ||
220 | */ | ||
221 | pmnc = xscale1pmu_read_pmnc(); | ||
222 | |||
223 | /* | ||
224 | * Write the value back to clear the overflow flags. Overflow | ||
225 | * flags remain in pmnc for use below. We also disable the PMU | ||
226 | * while we process the interrupt. | ||
227 | */ | ||
228 | xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); | ||
229 | |||
230 | if (!(pmnc & XSCALE1_OVERFLOWED_MASK)) | ||
231 | return IRQ_NONE; | ||
232 | |||
233 | regs = get_irq_regs(); | ||
234 | |||
235 | perf_sample_data_init(&data, 0); | ||
236 | |||
237 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
238 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
239 | struct perf_event *event = cpuc->events[idx]; | ||
240 | struct hw_perf_event *hwc; | ||
241 | |||
242 | if (!test_bit(idx, cpuc->active_mask)) | ||
243 | continue; | ||
244 | |||
245 | if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx)) | ||
246 | continue; | ||
247 | |||
248 | hwc = &event->hw; | ||
249 | armpmu_event_update(event, hwc, idx); | ||
250 | data.period = event->hw.last_period; | ||
251 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
252 | continue; | ||
253 | |||
254 | if (perf_event_overflow(event, 0, &data, regs)) | ||
255 | armpmu->disable(hwc, idx); | ||
256 | } | ||
257 | |||
258 | irq_work_run(); | ||
259 | |||
260 | /* | ||
261 | * Re-enable the PMU. | ||
262 | */ | ||
263 | pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE; | ||
264 | xscale1pmu_write_pmnc(pmnc); | ||
265 | |||
266 | return IRQ_HANDLED; | ||
267 | } | ||
268 | |||
269 | static void | ||
270 | xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) | ||
271 | { | ||
272 | unsigned long val, mask, evt, flags; | ||
273 | |||
274 | switch (idx) { | ||
275 | case XSCALE_CYCLE_COUNTER: | ||
276 | mask = 0; | ||
277 | evt = XSCALE1_CCOUNT_INT_EN; | ||
278 | break; | ||
279 | case XSCALE_COUNTER0: | ||
280 | mask = XSCALE1_COUNT0_EVT_MASK; | ||
281 | evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) | | ||
282 | XSCALE1_COUNT0_INT_EN; | ||
283 | break; | ||
284 | case XSCALE_COUNTER1: | ||
285 | mask = XSCALE1_COUNT1_EVT_MASK; | ||
286 | evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) | | ||
287 | XSCALE1_COUNT1_INT_EN; | ||
288 | break; | ||
289 | default: | ||
290 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
291 | return; | ||
292 | } | ||
293 | |||
294 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
295 | val = xscale1pmu_read_pmnc(); | ||
296 | val &= ~mask; | ||
297 | val |= evt; | ||
298 | xscale1pmu_write_pmnc(val); | ||
299 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
300 | } | ||
301 | |||
302 | static void | ||
303 | xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) | ||
304 | { | ||
305 | unsigned long val, mask, evt, flags; | ||
306 | |||
307 | switch (idx) { | ||
308 | case XSCALE_CYCLE_COUNTER: | ||
309 | mask = XSCALE1_CCOUNT_INT_EN; | ||
310 | evt = 0; | ||
311 | break; | ||
312 | case XSCALE_COUNTER0: | ||
313 | mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK; | ||
314 | evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT; | ||
315 | break; | ||
316 | case XSCALE_COUNTER1: | ||
317 | mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK; | ||
318 | evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT; | ||
319 | break; | ||
320 | default: | ||
321 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
326 | val = xscale1pmu_read_pmnc(); | ||
327 | val &= ~mask; | ||
328 | val |= evt; | ||
329 | xscale1pmu_write_pmnc(val); | ||
330 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
331 | } | ||
332 | |||
333 | static int | ||
334 | xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
335 | struct hw_perf_event *event) | ||
336 | { | ||
337 | if (XSCALE_PERFCTR_CCNT == event->config_base) { | ||
338 | if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask)) | ||
339 | return -EAGAIN; | ||
340 | |||
341 | return XSCALE_CYCLE_COUNTER; | ||
342 | } else { | ||
343 | if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) | ||
344 | return XSCALE_COUNTER1; | ||
345 | |||
346 | if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) | ||
347 | return XSCALE_COUNTER0; | ||
348 | |||
349 | return -EAGAIN; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | static void | ||
354 | xscale1pmu_start(void) | ||
355 | { | ||
356 | unsigned long flags, val; | ||
357 | |||
358 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
359 | val = xscale1pmu_read_pmnc(); | ||
360 | val |= XSCALE_PMU_ENABLE; | ||
361 | xscale1pmu_write_pmnc(val); | ||
362 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
363 | } | ||
364 | |||
365 | static void | ||
366 | xscale1pmu_stop(void) | ||
367 | { | ||
368 | unsigned long flags, val; | ||
369 | |||
370 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
371 | val = xscale1pmu_read_pmnc(); | ||
372 | val &= ~XSCALE_PMU_ENABLE; | ||
373 | xscale1pmu_write_pmnc(val); | ||
374 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
375 | } | ||
376 | |||
377 | static inline u32 | ||
378 | xscale1pmu_read_counter(int counter) | ||
379 | { | ||
380 | u32 val = 0; | ||
381 | |||
382 | switch (counter) { | ||
383 | case XSCALE_CYCLE_COUNTER: | ||
384 | asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val)); | ||
385 | break; | ||
386 | case XSCALE_COUNTER0: | ||
387 | asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val)); | ||
388 | break; | ||
389 | case XSCALE_COUNTER1: | ||
390 | asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val)); | ||
391 | break; | ||
392 | } | ||
393 | |||
394 | return val; | ||
395 | } | ||
396 | |||
397 | static inline void | ||
398 | xscale1pmu_write_counter(int counter, u32 val) | ||
399 | { | ||
400 | switch (counter) { | ||
401 | case XSCALE_CYCLE_COUNTER: | ||
402 | asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val)); | ||
403 | break; | ||
404 | case XSCALE_COUNTER0: | ||
405 | asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val)); | ||
406 | break; | ||
407 | case XSCALE_COUNTER1: | ||
408 | asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val)); | ||
409 | break; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | static const struct arm_pmu xscale1pmu = { | ||
414 | .id = ARM_PERF_PMU_ID_XSCALE1, | ||
415 | .name = "xscale1", | ||
416 | .handle_irq = xscale1pmu_handle_irq, | ||
417 | .enable = xscale1pmu_enable_event, | ||
418 | .disable = xscale1pmu_disable_event, | ||
419 | .read_counter = xscale1pmu_read_counter, | ||
420 | .write_counter = xscale1pmu_write_counter, | ||
421 | .get_event_idx = xscale1pmu_get_event_idx, | ||
422 | .start = xscale1pmu_start, | ||
423 | .stop = xscale1pmu_stop, | ||
424 | .cache_map = &xscale_perf_cache_map, | ||
425 | .event_map = &xscale_perf_map, | ||
426 | .raw_event_mask = 0xFF, | ||
427 | .num_events = 3, | ||
428 | .max_period = (1LLU << 32) - 1, | ||
429 | }; | ||
430 | |||
431 | static const struct arm_pmu *__init xscale1pmu_init(void) | ||
432 | { | ||
433 | return &xscale1pmu; | ||
434 | } | ||
435 | |||
436 | #define XSCALE2_OVERFLOWED_MASK 0x01f | ||
437 | #define XSCALE2_CCOUNT_OVERFLOW 0x001 | ||
438 | #define XSCALE2_COUNT0_OVERFLOW 0x002 | ||
439 | #define XSCALE2_COUNT1_OVERFLOW 0x004 | ||
440 | #define XSCALE2_COUNT2_OVERFLOW 0x008 | ||
441 | #define XSCALE2_COUNT3_OVERFLOW 0x010 | ||
442 | #define XSCALE2_CCOUNT_INT_EN 0x001 | ||
443 | #define XSCALE2_COUNT0_INT_EN 0x002 | ||
444 | #define XSCALE2_COUNT1_INT_EN 0x004 | ||
445 | #define XSCALE2_COUNT2_INT_EN 0x008 | ||
446 | #define XSCALE2_COUNT3_INT_EN 0x010 | ||
447 | #define XSCALE2_COUNT0_EVT_SHFT 0 | ||
448 | #define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT) | ||
449 | #define XSCALE2_COUNT1_EVT_SHFT 8 | ||
450 | #define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT) | ||
451 | #define XSCALE2_COUNT2_EVT_SHFT 16 | ||
452 | #define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT) | ||
453 | #define XSCALE2_COUNT3_EVT_SHFT 24 | ||
454 | #define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT) | ||
455 | |||
456 | static inline u32 | ||
457 | xscale2pmu_read_pmnc(void) | ||
458 | { | ||
459 | u32 val; | ||
460 | asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val)); | ||
461 | /* bits 1-2 and 4-23 are read-unpredictable */ | ||
462 | return val & 0xff000009; | ||
463 | } | ||
464 | |||
465 | static inline void | ||
466 | xscale2pmu_write_pmnc(u32 val) | ||
467 | { | ||
468 | /* bits 4-23 are write-as-0, 24-31 are write ignored */ | ||
469 | val &= 0xf; | ||
470 | asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val)); | ||
471 | } | ||
472 | |||
473 | static inline u32 | ||
474 | xscale2pmu_read_overflow_flags(void) | ||
475 | { | ||
476 | u32 val; | ||
477 | asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val)); | ||
478 | return val; | ||
479 | } | ||
480 | |||
481 | static inline void | ||
482 | xscale2pmu_write_overflow_flags(u32 val) | ||
483 | { | ||
484 | asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val)); | ||
485 | } | ||
486 | |||
487 | static inline u32 | ||
488 | xscale2pmu_read_event_select(void) | ||
489 | { | ||
490 | u32 val; | ||
491 | asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val)); | ||
492 | return val; | ||
493 | } | ||
494 | |||
495 | static inline void | ||
496 | xscale2pmu_write_event_select(u32 val) | ||
497 | { | ||
498 | asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val)); | ||
499 | } | ||
500 | |||
501 | static inline u32 | ||
502 | xscale2pmu_read_int_enable(void) | ||
503 | { | ||
504 | u32 val; | ||
505 | asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val)); | ||
506 | return val; | ||
507 | } | ||
508 | |||
509 | static void | ||
510 | xscale2pmu_write_int_enable(u32 val) | ||
511 | { | ||
512 | asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val)); | ||
513 | } | ||
514 | |||
515 | static inline int | ||
516 | xscale2_pmnc_counter_has_overflowed(unsigned long of_flags, | ||
517 | enum xscale_counters counter) | ||
518 | { | ||
519 | int ret = 0; | ||
520 | |||
521 | switch (counter) { | ||
522 | case XSCALE_CYCLE_COUNTER: | ||
523 | ret = of_flags & XSCALE2_CCOUNT_OVERFLOW; | ||
524 | break; | ||
525 | case XSCALE_COUNTER0: | ||
526 | ret = of_flags & XSCALE2_COUNT0_OVERFLOW; | ||
527 | break; | ||
528 | case XSCALE_COUNTER1: | ||
529 | ret = of_flags & XSCALE2_COUNT1_OVERFLOW; | ||
530 | break; | ||
531 | case XSCALE_COUNTER2: | ||
532 | ret = of_flags & XSCALE2_COUNT2_OVERFLOW; | ||
533 | break; | ||
534 | case XSCALE_COUNTER3: | ||
535 | ret = of_flags & XSCALE2_COUNT3_OVERFLOW; | ||
536 | break; | ||
537 | default: | ||
538 | WARN_ONCE(1, "invalid counter number (%d)\n", counter); | ||
539 | } | ||
540 | |||
541 | return ret; | ||
542 | } | ||
543 | |||
544 | static irqreturn_t | ||
545 | xscale2pmu_handle_irq(int irq_num, void *dev) | ||
546 | { | ||
547 | unsigned long pmnc, of_flags; | ||
548 | struct perf_sample_data data; | ||
549 | struct cpu_hw_events *cpuc; | ||
550 | struct pt_regs *regs; | ||
551 | int idx; | ||
552 | |||
553 | /* Disable the PMU. */ | ||
554 | pmnc = xscale2pmu_read_pmnc(); | ||
555 | xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); | ||
556 | |||
557 | /* Check the overflow flag register. */ | ||
558 | of_flags = xscale2pmu_read_overflow_flags(); | ||
559 | if (!(of_flags & XSCALE2_OVERFLOWED_MASK)) | ||
560 | return IRQ_NONE; | ||
561 | |||
562 | /* Clear the overflow bits. */ | ||
563 | xscale2pmu_write_overflow_flags(of_flags); | ||
564 | |||
565 | regs = get_irq_regs(); | ||
566 | |||
567 | perf_sample_data_init(&data, 0); | ||
568 | |||
569 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
570 | for (idx = 0; idx <= armpmu->num_events; ++idx) { | ||
571 | struct perf_event *event = cpuc->events[idx]; | ||
572 | struct hw_perf_event *hwc; | ||
573 | |||
574 | if (!test_bit(idx, cpuc->active_mask)) | ||
575 | continue; | ||
576 | |||
577 | if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx)) | ||
578 | continue; | ||
579 | |||
580 | hwc = &event->hw; | ||
581 | armpmu_event_update(event, hwc, idx); | ||
582 | data.period = event->hw.last_period; | ||
583 | if (!armpmu_event_set_period(event, hwc, idx)) | ||
584 | continue; | ||
585 | |||
586 | if (perf_event_overflow(event, 0, &data, regs)) | ||
587 | armpmu->disable(hwc, idx); | ||
588 | } | ||
589 | |||
590 | irq_work_run(); | ||
591 | |||
592 | /* | ||
593 | * Re-enable the PMU. | ||
594 | */ | ||
595 | pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE; | ||
596 | xscale2pmu_write_pmnc(pmnc); | ||
597 | |||
598 | return IRQ_HANDLED; | ||
599 | } | ||
600 | |||
601 | static void | ||
602 | xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) | ||
603 | { | ||
604 | unsigned long flags, ien, evtsel; | ||
605 | |||
606 | ien = xscale2pmu_read_int_enable(); | ||
607 | evtsel = xscale2pmu_read_event_select(); | ||
608 | |||
609 | switch (idx) { | ||
610 | case XSCALE_CYCLE_COUNTER: | ||
611 | ien |= XSCALE2_CCOUNT_INT_EN; | ||
612 | break; | ||
613 | case XSCALE_COUNTER0: | ||
614 | ien |= XSCALE2_COUNT0_INT_EN; | ||
615 | evtsel &= ~XSCALE2_COUNT0_EVT_MASK; | ||
616 | evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT; | ||
617 | break; | ||
618 | case XSCALE_COUNTER1: | ||
619 | ien |= XSCALE2_COUNT1_INT_EN; | ||
620 | evtsel &= ~XSCALE2_COUNT1_EVT_MASK; | ||
621 | evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT; | ||
622 | break; | ||
623 | case XSCALE_COUNTER2: | ||
624 | ien |= XSCALE2_COUNT2_INT_EN; | ||
625 | evtsel &= ~XSCALE2_COUNT2_EVT_MASK; | ||
626 | evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT; | ||
627 | break; | ||
628 | case XSCALE_COUNTER3: | ||
629 | ien |= XSCALE2_COUNT3_INT_EN; | ||
630 | evtsel &= ~XSCALE2_COUNT3_EVT_MASK; | ||
631 | evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT; | ||
632 | break; | ||
633 | default: | ||
634 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
635 | return; | ||
636 | } | ||
637 | |||
638 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
639 | xscale2pmu_write_event_select(evtsel); | ||
640 | xscale2pmu_write_int_enable(ien); | ||
641 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
642 | } | ||
643 | |||
644 | static void | ||
645 | xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) | ||
646 | { | ||
647 | unsigned long flags, ien, evtsel; | ||
648 | |||
649 | ien = xscale2pmu_read_int_enable(); | ||
650 | evtsel = xscale2pmu_read_event_select(); | ||
651 | |||
652 | switch (idx) { | ||
653 | case XSCALE_CYCLE_COUNTER: | ||
654 | ien &= ~XSCALE2_CCOUNT_INT_EN; | ||
655 | break; | ||
656 | case XSCALE_COUNTER0: | ||
657 | ien &= ~XSCALE2_COUNT0_INT_EN; | ||
658 | evtsel &= ~XSCALE2_COUNT0_EVT_MASK; | ||
659 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT; | ||
660 | break; | ||
661 | case XSCALE_COUNTER1: | ||
662 | ien &= ~XSCALE2_COUNT1_INT_EN; | ||
663 | evtsel &= ~XSCALE2_COUNT1_EVT_MASK; | ||
664 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT; | ||
665 | break; | ||
666 | case XSCALE_COUNTER2: | ||
667 | ien &= ~XSCALE2_COUNT2_INT_EN; | ||
668 | evtsel &= ~XSCALE2_COUNT2_EVT_MASK; | ||
669 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT; | ||
670 | break; | ||
671 | case XSCALE_COUNTER3: | ||
672 | ien &= ~XSCALE2_COUNT3_INT_EN; | ||
673 | evtsel &= ~XSCALE2_COUNT3_EVT_MASK; | ||
674 | evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT; | ||
675 | break; | ||
676 | default: | ||
677 | WARN_ONCE(1, "invalid counter number (%d)\n", idx); | ||
678 | return; | ||
679 | } | ||
680 | |||
681 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
682 | xscale2pmu_write_event_select(evtsel); | ||
683 | xscale2pmu_write_int_enable(ien); | ||
684 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
685 | } | ||
686 | |||
687 | static int | ||
688 | xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc, | ||
689 | struct hw_perf_event *event) | ||
690 | { | ||
691 | int idx = xscale1pmu_get_event_idx(cpuc, event); | ||
692 | if (idx >= 0) | ||
693 | goto out; | ||
694 | |||
695 | if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask)) | ||
696 | idx = XSCALE_COUNTER3; | ||
697 | else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask)) | ||
698 | idx = XSCALE_COUNTER2; | ||
699 | out: | ||
700 | return idx; | ||
701 | } | ||
702 | |||
703 | static void | ||
704 | xscale2pmu_start(void) | ||
705 | { | ||
706 | unsigned long flags, val; | ||
707 | |||
708 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
709 | val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; | ||
710 | val |= XSCALE_PMU_ENABLE; | ||
711 | xscale2pmu_write_pmnc(val); | ||
712 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
713 | } | ||
714 | |||
715 | static void | ||
716 | xscale2pmu_stop(void) | ||
717 | { | ||
718 | unsigned long flags, val; | ||
719 | |||
720 | raw_spin_lock_irqsave(&pmu_lock, flags); | ||
721 | val = xscale2pmu_read_pmnc(); | ||
722 | val &= ~XSCALE_PMU_ENABLE; | ||
723 | xscale2pmu_write_pmnc(val); | ||
724 | raw_spin_unlock_irqrestore(&pmu_lock, flags); | ||
725 | } | ||
726 | |||
727 | static inline u32 | ||
728 | xscale2pmu_read_counter(int counter) | ||
729 | { | ||
730 | u32 val = 0; | ||
731 | |||
732 | switch (counter) { | ||
733 | case XSCALE_CYCLE_COUNTER: | ||
734 | asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val)); | ||
735 | break; | ||
736 | case XSCALE_COUNTER0: | ||
737 | asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val)); | ||
738 | break; | ||
739 | case XSCALE_COUNTER1: | ||
740 | asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val)); | ||
741 | break; | ||
742 | case XSCALE_COUNTER2: | ||
743 | asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val)); | ||
744 | break; | ||
745 | case XSCALE_COUNTER3: | ||
746 | asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val)); | ||
747 | break; | ||
748 | } | ||
749 | |||
750 | return val; | ||
751 | } | ||
752 | |||
753 | static inline void | ||
754 | xscale2pmu_write_counter(int counter, u32 val) | ||
755 | { | ||
756 | switch (counter) { | ||
757 | case XSCALE_CYCLE_COUNTER: | ||
758 | asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val)); | ||
759 | break; | ||
760 | case XSCALE_COUNTER0: | ||
761 | asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val)); | ||
762 | break; | ||
763 | case XSCALE_COUNTER1: | ||
764 | asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val)); | ||
765 | break; | ||
766 | case XSCALE_COUNTER2: | ||
767 | asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val)); | ||
768 | break; | ||
769 | case XSCALE_COUNTER3: | ||
770 | asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val)); | ||
771 | break; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static const struct arm_pmu xscale2pmu = { | ||
776 | .id = ARM_PERF_PMU_ID_XSCALE2, | ||
777 | .name = "xscale2", | ||
778 | .handle_irq = xscale2pmu_handle_irq, | ||
779 | .enable = xscale2pmu_enable_event, | ||
780 | .disable = xscale2pmu_disable_event, | ||
781 | .read_counter = xscale2pmu_read_counter, | ||
782 | .write_counter = xscale2pmu_write_counter, | ||
783 | .get_event_idx = xscale2pmu_get_event_idx, | ||
784 | .start = xscale2pmu_start, | ||
785 | .stop = xscale2pmu_stop, | ||
786 | .cache_map = &xscale_perf_cache_map, | ||
787 | .event_map = &xscale_perf_map, | ||
788 | .raw_event_mask = 0xFF, | ||
789 | .num_events = 5, | ||
790 | .max_period = (1LLU << 32) - 1, | ||
791 | }; | ||
792 | |||
793 | static const struct arm_pmu *__init xscale2pmu_init(void) | ||
794 | { | ||
795 | return &xscale2pmu; | ||
796 | } | ||
797 | #else | ||
798 | static const struct arm_pmu *__init xscale1pmu_init(void) | ||
799 | { | ||
800 | return NULL; | ||
801 | } | ||
802 | |||
803 | static const struct arm_pmu *__init xscale2pmu_init(void) | ||
804 | { | ||
805 | return NULL; | ||
806 | } | ||
807 | #endif /* CONFIG_CPU_XSCALE */ | ||
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c new file mode 100644 index 000000000000..a4b1b0748fd3 --- /dev/null +++ b/arch/arm/kernel/pj4-cp0.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/kernel/pj4-cp0.c | ||
3 | * | ||
4 | * PJ4 iWMMXt coprocessor context switching and handling | ||
5 | * | ||
6 | * Copyright (c) 2010 Marvell International Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/signal.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <asm/thread_notify.h> | ||
21 | |||
22 | static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) | ||
23 | { | ||
24 | struct thread_info *thread = t; | ||
25 | |||
26 | switch (cmd) { | ||
27 | case THREAD_NOTIFY_FLUSH: | ||
28 | /* | ||
29 | * flush_thread() zeroes thread->fpstate, so no need | ||
30 | * to do anything here. | ||
31 | * | ||
32 | * FALLTHROUGH: Ensure we don't try to overwrite our newly | ||
33 | * initialised state information on the first fault. | ||
34 | */ | ||
35 | |||
36 | case THREAD_NOTIFY_EXIT: | ||
37 | iwmmxt_task_release(thread); | ||
38 | break; | ||
39 | |||
40 | case THREAD_NOTIFY_SWITCH: | ||
41 | iwmmxt_task_switch(thread); | ||
42 | break; | ||
43 | } | ||
44 | |||
45 | return NOTIFY_DONE; | ||
46 | } | ||
47 | |||
48 | static struct notifier_block iwmmxt_notifier_block = { | ||
49 | .notifier_call = iwmmxt_do, | ||
50 | }; | ||
51 | |||
52 | |||
53 | static u32 __init pj4_cp_access_read(void) | ||
54 | { | ||
55 | u32 value; | ||
56 | |||
57 | __asm__ __volatile__ ( | ||
58 | "mrc p15, 0, %0, c1, c0, 2\n\t" | ||
59 | : "=r" (value)); | ||
60 | return value; | ||
61 | } | ||
62 | |||
63 | static void __init pj4_cp_access_write(u32 value) | ||
64 | { | ||
65 | u32 temp; | ||
66 | |||
67 | __asm__ __volatile__ ( | ||
68 | "mcr p15, 0, %1, c1, c0, 2\n\t" | ||
69 | "mrc p15, 0, %0, c1, c0, 2\n\t" | ||
70 | "mov %0, %0\n\t" | ||
71 | "sub pc, pc, #4\n\t" | ||
72 | : "=r" (temp) : "r" (value)); | ||
73 | } | ||
74 | |||
75 | |||
76 | /* | ||
77 | * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy | ||
78 | * switch code handle iWMMXt context switching. | ||
79 | */ | ||
80 | static int __init pj4_cp0_init(void) | ||
81 | { | ||
82 | u32 cp_access; | ||
83 | |||
84 | cp_access = pj4_cp_access_read() & ~0xf; | ||
85 | pj4_cp_access_write(cp_access); | ||
86 | |||
87 | printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n"); | ||
88 | elf_hwcap |= HWCAP_IWMMXT; | ||
89 | thread_register_notifier(&iwmmxt_notifier_block); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | late_initcall(pj4_cp0_init); | ||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3e97483abcf0..19c6816db61e 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -1060,8 +1060,8 @@ static int ptrace_sethbpregs(struct task_struct *tsk, long num, | |||
1060 | goto out; | 1060 | goto out; |
1061 | 1061 | ||
1062 | if ((gen_type & implied_type) != gen_type) { | 1062 | if ((gen_type & implied_type) != gen_type) { |
1063 | ret = -EINVAL; | 1063 | ret = -EINVAL; |
1064 | goto out; | 1064 | goto out; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | attr.bp_len = gen_len; | 1067 | attr.bp_len = gen_len; |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8c1959590252..bbca89872c18 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/cache.h> | 16 | #include <linux/cache.h> |
17 | #include <linux/profile.h> | 17 | #include <linux/profile.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/ftrace.h> | ||
19 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
20 | #include <linux/err.h> | 21 | #include <linux/err.h> |
21 | #include <linux/cpu.h> | 22 | #include <linux/cpu.h> |
@@ -457,7 +458,7 @@ static void ipi_timer(void) | |||
457 | } | 458 | } |
458 | 459 | ||
459 | #ifdef CONFIG_LOCAL_TIMERS | 460 | #ifdef CONFIG_LOCAL_TIMERS |
460 | asmlinkage void __exception do_local_timer(struct pt_regs *regs) | 461 | asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) |
461 | { | 462 | { |
462 | struct pt_regs *old_regs = set_irq_regs(regs); | 463 | struct pt_regs *old_regs = set_irq_regs(regs); |
463 | int cpu = smp_processor_id(); | 464 | int cpu = smp_processor_id(); |
@@ -544,7 +545,7 @@ static void ipi_cpu_stop(unsigned int cpu) | |||
544 | * | 545 | * |
545 | * Bit 0 - Inter-processor function call | 546 | * Bit 0 - Inter-processor function call |
546 | */ | 547 | */ |
547 | asmlinkage void __exception do_IPI(struct pt_regs *regs) | 548 | asmlinkage void __exception_irq_entry do_IPI(struct pt_regs *regs) |
548 | { | 549 | { |
549 | unsigned int cpu = smp_processor_id(); | 550 | unsigned int cpu = smp_processor_id(); |
550 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); | 551 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index cead8893b46b..897c1a8f1694 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -101,6 +101,7 @@ SECTIONS | |||
101 | __exception_text_start = .; | 101 | __exception_text_start = .; |
102 | *(.exception.text) | 102 | *(.exception.text) |
103 | __exception_text_end = .; | 103 | __exception_text_end = .; |
104 | IRQENTRY_TEXT | ||
104 | TEXT_TEXT | 105 | TEXT_TEXT |
105 | SCHED_TEXT | 106 | SCHED_TEXT |
106 | LOCK_TEXT | 107 | LOCK_TEXT |
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index 90fe9ab8591d..08e5c8759502 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/compiler.h> | 18 | #include <linux/compiler.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/dma-mapping.h> | ||
20 | #include <linux/serial_core.h> | 21 | #include <linux/serial_core.h> |
21 | #include <linux/serial_8250.h> | 22 | #include <linux/serial_8250.h> |
22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
@@ -108,10 +109,63 @@ static void __init cns3420_early_serial_setup(void) | |||
108 | } | 109 | } |
109 | 110 | ||
110 | /* | 111 | /* |
112 | * USB | ||
113 | */ | ||
114 | static struct resource cns3xxx_usb_ehci_resources[] = { | ||
115 | [0] = { | ||
116 | .start = CNS3XXX_USB_BASE, | ||
117 | .end = CNS3XXX_USB_BASE + SZ_16M - 1, | ||
118 | .flags = IORESOURCE_MEM, | ||
119 | }, | ||
120 | [1] = { | ||
121 | .start = IRQ_CNS3XXX_USB_EHCI, | ||
122 | .flags = IORESOURCE_IRQ, | ||
123 | }, | ||
124 | }; | ||
125 | |||
126 | static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32); | ||
127 | |||
128 | static struct platform_device cns3xxx_usb_ehci_device = { | ||
129 | .name = "cns3xxx-ehci", | ||
130 | .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources), | ||
131 | .resource = cns3xxx_usb_ehci_resources, | ||
132 | .dev = { | ||
133 | .dma_mask = &cns3xxx_usb_ehci_dma_mask, | ||
134 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
135 | }, | ||
136 | }; | ||
137 | |||
138 | static struct resource cns3xxx_usb_ohci_resources[] = { | ||
139 | [0] = { | ||
140 | .start = CNS3XXX_USB_OHCI_BASE, | ||
141 | .end = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1, | ||
142 | .flags = IORESOURCE_MEM, | ||
143 | }, | ||
144 | [1] = { | ||
145 | .start = IRQ_CNS3XXX_USB_OHCI, | ||
146 | .flags = IORESOURCE_IRQ, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32); | ||
151 | |||
152 | static struct platform_device cns3xxx_usb_ohci_device = { | ||
153 | .name = "cns3xxx-ohci", | ||
154 | .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources), | ||
155 | .resource = cns3xxx_usb_ohci_resources, | ||
156 | .dev = { | ||
157 | .dma_mask = &cns3xxx_usb_ohci_dma_mask, | ||
158 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
159 | }, | ||
160 | }; | ||
161 | |||
162 | /* | ||
111 | * Initialization | 163 | * Initialization |
112 | */ | 164 | */ |
113 | static struct platform_device *cns3420_pdevs[] __initdata = { | 165 | static struct platform_device *cns3420_pdevs[] __initdata = { |
114 | &cns3420_nor_pdev, | 166 | &cns3420_nor_pdev, |
167 | &cns3xxx_usb_ehci_device, | ||
168 | &cns3xxx_usb_ohci_device, | ||
115 | }; | 169 | }; |
116 | 170 | ||
117 | static void __init cns3420_init(void) | 171 | static void __init cns3420_init(void) |
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h index 6b33ec11346e..73898a7835d3 100644 --- a/arch/arm/mach-cns3xxx/core.h +++ b/arch/arm/mach-cns3xxx/core.h | |||
@@ -17,7 +17,5 @@ extern struct sys_timer cns3xxx_timer; | |||
17 | void __init cns3xxx_map_io(void); | 17 | void __init cns3xxx_map_io(void); |
18 | void __init cns3xxx_init_irq(void); | 18 | void __init cns3xxx_init_irq(void); |
19 | void cns3xxx_power_off(void); | 19 | void cns3xxx_power_off(void); |
20 | void cns3xxx_pwr_power_up(unsigned int block); | ||
21 | void cns3xxx_pwr_power_down(unsigned int block); | ||
22 | 20 | ||
23 | #endif /* __CNS3XXX_CORE_H */ | 21 | #endif /* __CNS3XXX_CORE_H */ |
diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c index 50b4d31c27c0..79d1fb02c23f 100644 --- a/arch/arm/mach-cns3xxx/devices.c +++ b/arch/arm/mach-cns3xxx/devices.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <mach/cns3xxx.h> | 19 | #include <mach/cns3xxx.h> |
20 | #include <mach/irqs.h> | 20 | #include <mach/irqs.h> |
21 | #include <mach/pm.h> | ||
21 | #include "core.h" | 22 | #include "core.h" |
22 | #include "devices.h" | 23 | #include "devices.h" |
23 | 24 | ||
diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h index 6dbce13771ca..191c8e57f289 100644 --- a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h +++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h | |||
@@ -165,7 +165,6 @@ | |||
165 | #define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000 | 165 | #define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000 |
166 | 166 | ||
167 | #define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */ | 167 | #define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */ |
168 | #define CNS3XXX_USB_BASE_VIRT 0xFFF16000 | ||
169 | 168 | ||
170 | #define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */ | 169 | #define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */ |
171 | #define CNS3XXX_SATA2_SIZE SZ_16M | 170 | #define CNS3XXX_SATA2_SIZE SZ_16M |
@@ -184,7 +183,6 @@ | |||
184 | #define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000 | 183 | #define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000 |
185 | 184 | ||
186 | #define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */ | 185 | #define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */ |
187 | #define CNS3XXX_USB_OHCI_BASE_VIRT 0xFFF1C000 | ||
188 | 186 | ||
189 | #define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */ | 187 | #define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */ |
190 | #define CNS3XXX_L2C_BASE_VIRT 0xFFF27000 | 188 | #define CNS3XXX_L2C_BASE_VIRT 0xFFF27000 |
diff --git a/arch/arm/mach-cns3xxx/include/mach/pm.h b/arch/arm/mach-cns3xxx/include/mach/pm.h new file mode 100644 index 000000000000..6eae7f764d1d --- /dev/null +++ b/arch/arm/mach-cns3xxx/include/mach/pm.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Copyright 2000 Deep Blue Solutions Ltd | ||
3 | * Copyright 2004 ARM Limited | ||
4 | * Copyright 2008 Cavium Networks | ||
5 | * | ||
6 | * This file is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License, Version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __CNS3XXX_PM_H | ||
12 | #define __CNS3XXX_PM_H | ||
13 | |||
14 | #include <asm/atomic.h> | ||
15 | |||
16 | void cns3xxx_pwr_clk_en(unsigned int block); | ||
17 | void cns3xxx_pwr_clk_dis(unsigned int block); | ||
18 | void cns3xxx_pwr_power_up(unsigned int block); | ||
19 | void cns3xxx_pwr_power_down(unsigned int block); | ||
20 | |||
21 | extern atomic_t usb_pwr_ref; | ||
22 | |||
23 | #endif /* __CNS3XXX_PM_H */ | ||
diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c index 38e44706feab..5e579552aa54 100644 --- a/arch/arm/mach-cns3xxx/pm.c +++ b/arch/arm/mach-cns3xxx/pm.c | |||
@@ -6,10 +6,14 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | ||
9 | #include <linux/io.h> | 11 | #include <linux/io.h> |
10 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <asm/atomic.h> | ||
11 | #include <mach/system.h> | 14 | #include <mach/system.h> |
12 | #include <mach/cns3xxx.h> | 15 | #include <mach/cns3xxx.h> |
16 | #include <mach/pm.h> | ||
13 | 17 | ||
14 | void cns3xxx_pwr_clk_en(unsigned int block) | 18 | void cns3xxx_pwr_clk_en(unsigned int block) |
15 | { | 19 | { |
@@ -18,6 +22,16 @@ void cns3xxx_pwr_clk_en(unsigned int block) | |||
18 | reg |= (block & PM_CLK_GATE_REG_MASK); | 22 | reg |= (block & PM_CLK_GATE_REG_MASK); |
19 | __raw_writel(reg, PM_CLK_GATE_REG); | 23 | __raw_writel(reg, PM_CLK_GATE_REG); |
20 | } | 24 | } |
25 | EXPORT_SYMBOL(cns3xxx_pwr_clk_en); | ||
26 | |||
27 | void cns3xxx_pwr_clk_dis(unsigned int block) | ||
28 | { | ||
29 | u32 reg = __raw_readl(PM_CLK_GATE_REG); | ||
30 | |||
31 | reg &= ~(block & PM_CLK_GATE_REG_MASK); | ||
32 | __raw_writel(reg, PM_CLK_GATE_REG); | ||
33 | } | ||
34 | EXPORT_SYMBOL(cns3xxx_pwr_clk_dis); | ||
21 | 35 | ||
22 | void cns3xxx_pwr_power_up(unsigned int block) | 36 | void cns3xxx_pwr_power_up(unsigned int block) |
23 | { | 37 | { |
@@ -29,6 +43,7 @@ void cns3xxx_pwr_power_up(unsigned int block) | |||
29 | /* Wait for 300us for the PLL output clock locked. */ | 43 | /* Wait for 300us for the PLL output clock locked. */ |
30 | udelay(300); | 44 | udelay(300); |
31 | }; | 45 | }; |
46 | EXPORT_SYMBOL(cns3xxx_pwr_power_up); | ||
32 | 47 | ||
33 | void cns3xxx_pwr_power_down(unsigned int block) | 48 | void cns3xxx_pwr_power_down(unsigned int block) |
34 | { | 49 | { |
@@ -38,6 +53,7 @@ void cns3xxx_pwr_power_down(unsigned int block) | |||
38 | reg |= (block & CNS3XXX_PWR_PLL_ALL); | 53 | reg |= (block & CNS3XXX_PWR_PLL_ALL); |
39 | __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG); | 54 | __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG); |
40 | }; | 55 | }; |
56 | EXPORT_SYMBOL(cns3xxx_pwr_power_down); | ||
41 | 57 | ||
42 | static void cns3xxx_pwr_soft_rst_force(unsigned int block) | 58 | static void cns3xxx_pwr_soft_rst_force(unsigned int block) |
43 | { | 59 | { |
@@ -51,11 +67,13 @@ static void cns3xxx_pwr_soft_rst_force(unsigned int block) | |||
51 | reg &= ~(block & PM_SOFT_RST_REG_MASK); | 67 | reg &= ~(block & PM_SOFT_RST_REG_MASK); |
52 | } else { | 68 | } else { |
53 | reg &= ~(block & PM_SOFT_RST_REG_MASK); | 69 | reg &= ~(block & PM_SOFT_RST_REG_MASK); |
70 | __raw_writel(reg, PM_SOFT_RST_REG); | ||
54 | reg |= (block & PM_SOFT_RST_REG_MASK); | 71 | reg |= (block & PM_SOFT_RST_REG_MASK); |
55 | } | 72 | } |
56 | 73 | ||
57 | __raw_writel(reg, PM_SOFT_RST_REG); | 74 | __raw_writel(reg, PM_SOFT_RST_REG); |
58 | } | 75 | } |
76 | EXPORT_SYMBOL(cns3xxx_pwr_soft_rst_force); | ||
59 | 77 | ||
60 | void cns3xxx_pwr_soft_rst(unsigned int block) | 78 | void cns3xxx_pwr_soft_rst(unsigned int block) |
61 | { | 79 | { |
@@ -69,6 +87,7 @@ void cns3xxx_pwr_soft_rst(unsigned int block) | |||
69 | } | 87 | } |
70 | cns3xxx_pwr_soft_rst_force(block); | 88 | cns3xxx_pwr_soft_rst_force(block); |
71 | } | 89 | } |
90 | EXPORT_SYMBOL(cns3xxx_pwr_soft_rst); | ||
72 | 91 | ||
73 | void arch_reset(char mode, const char *cmd) | 92 | void arch_reset(char mode, const char *cmd) |
74 | { | 93 | { |
@@ -99,3 +118,7 @@ int cns3xxx_cpu_clock(void) | |||
99 | 118 | ||
100 | return cpu; | 119 | return cpu; |
101 | } | 120 | } |
121 | EXPORT_SYMBOL(cns3xxx_cpu_clock); | ||
122 | |||
123 | atomic_t usb_pwr_ref = ATOMIC_INIT(0); | ||
124 | EXPORT_SYMBOL(usb_pwr_ref); | ||
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index b77b860b36d7..32f147998cd9 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig | |||
@@ -61,6 +61,8 @@ config MACH_DAVINCI_EVM | |||
61 | bool "TI DM644x EVM" | 61 | bool "TI DM644x EVM" |
62 | default ARCH_DAVINCI_DM644x | 62 | default ARCH_DAVINCI_DM644x |
63 | depends on ARCH_DAVINCI_DM644x | 63 | depends on ARCH_DAVINCI_DM644x |
64 | select MISC_DEVICES | ||
65 | select EEPROM_AT24 | ||
64 | help | 66 | help |
65 | Configure this option to specify the whether the board used | 67 | Configure this option to specify the whether the board used |
66 | for development is a DM644x EVM | 68 | for development is a DM644x EVM |
@@ -68,6 +70,8 @@ config MACH_DAVINCI_EVM | |||
68 | config MACH_SFFSDR | 70 | config MACH_SFFSDR |
69 | bool "Lyrtech SFFSDR" | 71 | bool "Lyrtech SFFSDR" |
70 | depends on ARCH_DAVINCI_DM644x | 72 | depends on ARCH_DAVINCI_DM644x |
73 | select MISC_DEVICES | ||
74 | select EEPROM_AT24 | ||
71 | help | 75 | help |
72 | Say Y here to select the Lyrtech Small Form Factor | 76 | Say Y here to select the Lyrtech Small Form Factor |
73 | Software Defined Radio (SFFSDR) board. | 77 | Software Defined Radio (SFFSDR) board. |
@@ -99,6 +103,8 @@ config MACH_DAVINCI_DM6467_EVM | |||
99 | default ARCH_DAVINCI_DM646x | 103 | default ARCH_DAVINCI_DM646x |
100 | depends on ARCH_DAVINCI_DM646x | 104 | depends on ARCH_DAVINCI_DM646x |
101 | select MACH_DAVINCI_DM6467TEVM | 105 | select MACH_DAVINCI_DM6467TEVM |
106 | select MISC_DEVICES | ||
107 | select EEPROM_AT24 | ||
102 | help | 108 | help |
103 | Configure this option to specify the whether the board used | 109 | Configure this option to specify the whether the board used |
104 | for development is a DM6467 EVM | 110 | for development is a DM6467 EVM |
@@ -110,6 +116,8 @@ config MACH_DAVINCI_DM365_EVM | |||
110 | bool "TI DM365 EVM" | 116 | bool "TI DM365 EVM" |
111 | default ARCH_DAVINCI_DM365 | 117 | default ARCH_DAVINCI_DM365 |
112 | depends on ARCH_DAVINCI_DM365 | 118 | depends on ARCH_DAVINCI_DM365 |
119 | select MISC_DEVICES | ||
120 | select EEPROM_AT24 | ||
113 | help | 121 | help |
114 | Configure this option to specify whether the board used | 122 | Configure this option to specify whether the board used |
115 | for development is a DM365 EVM | 123 | for development is a DM365 EVM |
@@ -119,6 +127,8 @@ config MACH_DAVINCI_DA830_EVM | |||
119 | default ARCH_DAVINCI_DA830 | 127 | default ARCH_DAVINCI_DA830 |
120 | depends on ARCH_DAVINCI_DA830 | 128 | depends on ARCH_DAVINCI_DA830 |
121 | select GPIO_PCF857X | 129 | select GPIO_PCF857X |
130 | select MISC_DEVICES | ||
131 | select EEPROM_AT24 | ||
122 | help | 132 | help |
123 | Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. | 133 | Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. |
124 | 134 | ||
@@ -148,7 +158,6 @@ config MACH_DAVINCI_DA850_EVM | |||
148 | bool "TI DA850/OMAP-L138/AM18x Reference Platform" | 158 | bool "TI DA850/OMAP-L138/AM18x Reference Platform" |
149 | default ARCH_DAVINCI_DA850 | 159 | default ARCH_DAVINCI_DA850 |
150 | depends on ARCH_DAVINCI_DA850 | 160 | depends on ARCH_DAVINCI_DA850 |
151 | select GPIO_PCA953X | ||
152 | help | 161 | help |
153 | Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module. | 162 | Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module. |
154 | 163 | ||
@@ -178,6 +187,12 @@ config DA850_UI_RMII | |||
178 | 187 | ||
179 | endchoice | 188 | endchoice |
180 | 189 | ||
190 | config GPIO_PCA953X | ||
191 | default MACH_DAVINCI_DA850_EVM | ||
192 | |||
193 | config KEYBOARD_GPIO_POLLED | ||
194 | default MACH_DAVINCI_DA850_EVM | ||
195 | |||
181 | config MACH_TNETV107X | 196 | config MACH_TNETV107X |
182 | bool "TI TNETV107X Reference Platform" | 197 | bool "TI TNETV107X Reference Platform" |
183 | default ARCH_DAVINCI_TNETV107X | 198 | default ARCH_DAVINCI_TNETV107X |
@@ -188,6 +203,8 @@ config MACH_TNETV107X | |||
188 | config MACH_MITYOMAPL138 | 203 | config MACH_MITYOMAPL138 |
189 | bool "Critical Link MityDSP-L138/MityARM-1808 SoM" | 204 | bool "Critical Link MityDSP-L138/MityARM-1808 SoM" |
190 | depends on ARCH_DAVINCI_DA850 | 205 | depends on ARCH_DAVINCI_DA850 |
206 | select MISC_DEVICES | ||
207 | select EEPROM_AT24 | ||
191 | help | 208 | help |
192 | Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 | 209 | Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 |
193 | System on Module. Information on this SoM may be found at | 210 | System on Module. Information on this SoM may be found at |
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c index 9c3f500fc12f..1ce70a91f2e9 100644 --- a/arch/arm/mach-davinci/aemif.c +++ b/arch/arm/mach-davinci/aemif.c | |||
@@ -90,7 +90,7 @@ int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, | |||
90 | void __iomem *base, unsigned cs) | 90 | void __iomem *base, unsigned cs) |
91 | { | 91 | { |
92 | unsigned set, val; | 92 | unsigned set, val; |
93 | unsigned ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; | 93 | int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; |
94 | unsigned offset = A1CR_OFFSET + cs * 4; | 94 | unsigned offset = A1CR_OFFSET + cs * 4; |
95 | struct clk *aemif_clk; | 95 | struct clk *aemif_clk; |
96 | unsigned long clkrate; | 96 | unsigned long clkrate; |
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index c6e11c682e4c..b01fb2ab944a 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
@@ -17,8 +17,10 @@ | |||
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/i2c/at24.h> | 18 | #include <linux/i2c/at24.h> |
19 | #include <linux/i2c/pca953x.h> | 19 | #include <linux/i2c/pca953x.h> |
20 | #include <linux/input.h> | ||
20 | #include <linux/mfd/tps6507x.h> | 21 | #include <linux/mfd/tps6507x.h> |
21 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/gpio_keys.h> | ||
22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
23 | #include <linux/mtd/mtd.h> | 25 | #include <linux/mtd/mtd.h> |
24 | #include <linux/mtd/nand.h> | 26 | #include <linux/mtd/nand.h> |
@@ -266,34 +268,115 @@ static inline void da850_evm_setup_emac_rmii(int rmii_sel) | |||
266 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 268 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
267 | 269 | ||
268 | soc_info->emac_pdata->rmii_en = 1; | 270 | soc_info->emac_pdata->rmii_en = 1; |
269 | gpio_set_value(rmii_sel, 0); | 271 | gpio_set_value_cansleep(rmii_sel, 0); |
270 | } | 272 | } |
271 | #else | 273 | #else |
272 | static inline void da850_evm_setup_emac_rmii(int rmii_sel) { } | 274 | static inline void da850_evm_setup_emac_rmii(int rmii_sel) { } |
273 | #endif | 275 | #endif |
274 | 276 | ||
277 | |||
278 | #define DA850_KEYS_DEBOUNCE_MS 10 | ||
279 | /* | ||
280 | * At 200ms polling interval it is possible to miss an | ||
281 | * event by tapping very lightly on the push button but most | ||
282 | * pushes do result in an event; longer intervals require the | ||
283 | * user to hold the button whereas shorter intervals require | ||
284 | * more CPU time for polling. | ||
285 | */ | ||
286 | #define DA850_GPIO_KEYS_POLL_MS 200 | ||
287 | |||
288 | enum da850_evm_ui_exp_pins { | ||
289 | DA850_EVM_UI_EXP_SEL_C = 5, | ||
290 | DA850_EVM_UI_EXP_SEL_B, | ||
291 | DA850_EVM_UI_EXP_SEL_A, | ||
292 | DA850_EVM_UI_EXP_PB8, | ||
293 | DA850_EVM_UI_EXP_PB7, | ||
294 | DA850_EVM_UI_EXP_PB6, | ||
295 | DA850_EVM_UI_EXP_PB5, | ||
296 | DA850_EVM_UI_EXP_PB4, | ||
297 | DA850_EVM_UI_EXP_PB3, | ||
298 | DA850_EVM_UI_EXP_PB2, | ||
299 | DA850_EVM_UI_EXP_PB1, | ||
300 | }; | ||
301 | |||
302 | static const char const *da850_evm_ui_exp[] = { | ||
303 | [DA850_EVM_UI_EXP_SEL_C] = "sel_c", | ||
304 | [DA850_EVM_UI_EXP_SEL_B] = "sel_b", | ||
305 | [DA850_EVM_UI_EXP_SEL_A] = "sel_a", | ||
306 | [DA850_EVM_UI_EXP_PB8] = "pb8", | ||
307 | [DA850_EVM_UI_EXP_PB7] = "pb7", | ||
308 | [DA850_EVM_UI_EXP_PB6] = "pb6", | ||
309 | [DA850_EVM_UI_EXP_PB5] = "pb5", | ||
310 | [DA850_EVM_UI_EXP_PB4] = "pb4", | ||
311 | [DA850_EVM_UI_EXP_PB3] = "pb3", | ||
312 | [DA850_EVM_UI_EXP_PB2] = "pb2", | ||
313 | [DA850_EVM_UI_EXP_PB1] = "pb1", | ||
314 | }; | ||
315 | |||
316 | #define DA850_N_UI_PB 8 | ||
317 | |||
318 | static struct gpio_keys_button da850_evm_ui_keys[] = { | ||
319 | [0 ... DA850_N_UI_PB - 1] = { | ||
320 | .type = EV_KEY, | ||
321 | .active_low = 1, | ||
322 | .wakeup = 0, | ||
323 | .debounce_interval = DA850_KEYS_DEBOUNCE_MS, | ||
324 | .code = -1, /* assigned at runtime */ | ||
325 | .gpio = -1, /* assigned at runtime */ | ||
326 | .desc = NULL, /* assigned at runtime */ | ||
327 | }, | ||
328 | }; | ||
329 | |||
330 | static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = { | ||
331 | .buttons = da850_evm_ui_keys, | ||
332 | .nbuttons = ARRAY_SIZE(da850_evm_ui_keys), | ||
333 | .poll_interval = DA850_GPIO_KEYS_POLL_MS, | ||
334 | }; | ||
335 | |||
336 | static struct platform_device da850_evm_ui_keys_device = { | ||
337 | .name = "gpio-keys-polled", | ||
338 | .id = 0, | ||
339 | .dev = { | ||
340 | .platform_data = &da850_evm_ui_keys_pdata | ||
341 | }, | ||
342 | }; | ||
343 | |||
344 | static void da850_evm_ui_keys_init(unsigned gpio) | ||
345 | { | ||
346 | int i; | ||
347 | struct gpio_keys_button *button; | ||
348 | |||
349 | for (i = 0; i < DA850_N_UI_PB; i++) { | ||
350 | button = &da850_evm_ui_keys[i]; | ||
351 | button->code = KEY_F8 - i; | ||
352 | button->desc = (char *) | ||
353 | da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i]; | ||
354 | button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i; | ||
355 | } | ||
356 | } | ||
357 | |||
275 | static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio, | 358 | static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio, |
276 | unsigned ngpio, void *c) | 359 | unsigned ngpio, void *c) |
277 | { | 360 | { |
278 | int sel_a, sel_b, sel_c, ret; | 361 | int sel_a, sel_b, sel_c, ret; |
279 | 362 | ||
280 | sel_a = gpio + 7; | 363 | sel_a = gpio + DA850_EVM_UI_EXP_SEL_A; |
281 | sel_b = gpio + 6; | 364 | sel_b = gpio + DA850_EVM_UI_EXP_SEL_B; |
282 | sel_c = gpio + 5; | 365 | sel_c = gpio + DA850_EVM_UI_EXP_SEL_C; |
283 | 366 | ||
284 | ret = gpio_request(sel_a, "sel_a"); | 367 | ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]); |
285 | if (ret) { | 368 | if (ret) { |
286 | pr_warning("Cannot open UI expander pin %d\n", sel_a); | 369 | pr_warning("Cannot open UI expander pin %d\n", sel_a); |
287 | goto exp_setup_sela_fail; | 370 | goto exp_setup_sela_fail; |
288 | } | 371 | } |
289 | 372 | ||
290 | ret = gpio_request(sel_b, "sel_b"); | 373 | ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]); |
291 | if (ret) { | 374 | if (ret) { |
292 | pr_warning("Cannot open UI expander pin %d\n", sel_b); | 375 | pr_warning("Cannot open UI expander pin %d\n", sel_b); |
293 | goto exp_setup_selb_fail; | 376 | goto exp_setup_selb_fail; |
294 | } | 377 | } |
295 | 378 | ||
296 | ret = gpio_request(sel_c, "sel_c"); | 379 | ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]); |
297 | if (ret) { | 380 | if (ret) { |
298 | pr_warning("Cannot open UI expander pin %d\n", sel_c); | 381 | pr_warning("Cannot open UI expander pin %d\n", sel_c); |
299 | goto exp_setup_selc_fail; | 382 | goto exp_setup_selc_fail; |
@@ -304,6 +387,13 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio, | |||
304 | gpio_direction_output(sel_b, 1); | 387 | gpio_direction_output(sel_b, 1); |
305 | gpio_direction_output(sel_c, 1); | 388 | gpio_direction_output(sel_c, 1); |
306 | 389 | ||
390 | da850_evm_ui_keys_init(gpio); | ||
391 | ret = platform_device_register(&da850_evm_ui_keys_device); | ||
392 | if (ret) { | ||
393 | pr_warning("Could not register UI GPIO expander push-buttons"); | ||
394 | goto exp_setup_keys_fail; | ||
395 | } | ||
396 | |||
307 | ui_card_detected = 1; | 397 | ui_card_detected = 1; |
308 | pr_info("DA850/OMAP-L138 EVM UI card detected\n"); | 398 | pr_info("DA850/OMAP-L138 EVM UI card detected\n"); |
309 | 399 | ||
@@ -313,6 +403,8 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio, | |||
313 | 403 | ||
314 | return 0; | 404 | return 0; |
315 | 405 | ||
406 | exp_setup_keys_fail: | ||
407 | gpio_free(sel_c); | ||
316 | exp_setup_selc_fail: | 408 | exp_setup_selc_fail: |
317 | gpio_free(sel_b); | 409 | gpio_free(sel_b); |
318 | exp_setup_selb_fail: | 410 | exp_setup_selb_fail: |
@@ -324,14 +416,192 @@ exp_setup_sela_fail: | |||
324 | static int da850_evm_ui_expander_teardown(struct i2c_client *client, | 416 | static int da850_evm_ui_expander_teardown(struct i2c_client *client, |
325 | unsigned gpio, unsigned ngpio, void *c) | 417 | unsigned gpio, unsigned ngpio, void *c) |
326 | { | 418 | { |
419 | platform_device_unregister(&da850_evm_ui_keys_device); | ||
420 | |||
327 | /* deselect all functionalities */ | 421 | /* deselect all functionalities */ |
328 | gpio_set_value(gpio + 5, 1); | 422 | gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_C, 1); |
329 | gpio_set_value(gpio + 6, 1); | 423 | gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_B, 1); |
330 | gpio_set_value(gpio + 7, 1); | 424 | gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_A, 1); |
425 | |||
426 | gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C); | ||
427 | gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B); | ||
428 | gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A); | ||
429 | |||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | /* assign the baseboard expander's GPIOs after the UI board's */ | ||
434 | #define DA850_UI_EXPANDER_N_GPIOS ARRAY_SIZE(da850_evm_ui_exp) | ||
435 | #define DA850_BB_EXPANDER_GPIO_BASE (DAVINCI_N_GPIO + DA850_UI_EXPANDER_N_GPIOS) | ||
436 | |||
437 | enum da850_evm_bb_exp_pins { | ||
438 | DA850_EVM_BB_EXP_DEEP_SLEEP_EN = 0, | ||
439 | DA850_EVM_BB_EXP_SW_RST, | ||
440 | DA850_EVM_BB_EXP_TP_23, | ||
441 | DA850_EVM_BB_EXP_TP_22, | ||
442 | DA850_EVM_BB_EXP_TP_21, | ||
443 | DA850_EVM_BB_EXP_USER_PB1, | ||
444 | DA850_EVM_BB_EXP_USER_LED2, | ||
445 | DA850_EVM_BB_EXP_USER_LED1, | ||
446 | DA850_EVM_BB_EXP_USER_SW1, | ||
447 | DA850_EVM_BB_EXP_USER_SW2, | ||
448 | DA850_EVM_BB_EXP_USER_SW3, | ||
449 | DA850_EVM_BB_EXP_USER_SW4, | ||
450 | DA850_EVM_BB_EXP_USER_SW5, | ||
451 | DA850_EVM_BB_EXP_USER_SW6, | ||
452 | DA850_EVM_BB_EXP_USER_SW7, | ||
453 | DA850_EVM_BB_EXP_USER_SW8 | ||
454 | }; | ||
455 | |||
456 | static const char const *da850_evm_bb_exp[] = { | ||
457 | [DA850_EVM_BB_EXP_DEEP_SLEEP_EN] = "deep_sleep_en", | ||
458 | [DA850_EVM_BB_EXP_SW_RST] = "sw_rst", | ||
459 | [DA850_EVM_BB_EXP_TP_23] = "tp_23", | ||
460 | [DA850_EVM_BB_EXP_TP_22] = "tp_22", | ||
461 | [DA850_EVM_BB_EXP_TP_21] = "tp_21", | ||
462 | [DA850_EVM_BB_EXP_USER_PB1] = "user_pb1", | ||
463 | [DA850_EVM_BB_EXP_USER_LED2] = "user_led2", | ||
464 | [DA850_EVM_BB_EXP_USER_LED1] = "user_led1", | ||
465 | [DA850_EVM_BB_EXP_USER_SW1] = "user_sw1", | ||
466 | [DA850_EVM_BB_EXP_USER_SW2] = "user_sw2", | ||
467 | [DA850_EVM_BB_EXP_USER_SW3] = "user_sw3", | ||
468 | [DA850_EVM_BB_EXP_USER_SW4] = "user_sw4", | ||
469 | [DA850_EVM_BB_EXP_USER_SW5] = "user_sw5", | ||
470 | [DA850_EVM_BB_EXP_USER_SW6] = "user_sw6", | ||
471 | [DA850_EVM_BB_EXP_USER_SW7] = "user_sw7", | ||
472 | [DA850_EVM_BB_EXP_USER_SW8] = "user_sw8", | ||
473 | }; | ||
474 | |||
475 | #define DA850_N_BB_USER_SW 8 | ||
476 | |||
477 | static struct gpio_keys_button da850_evm_bb_keys[] = { | ||
478 | [0] = { | ||
479 | .type = EV_KEY, | ||
480 | .active_low = 1, | ||
481 | .wakeup = 0, | ||
482 | .debounce_interval = DA850_KEYS_DEBOUNCE_MS, | ||
483 | .code = KEY_PROG1, | ||
484 | .desc = NULL, /* assigned at runtime */ | ||
485 | .gpio = -1, /* assigned at runtime */ | ||
486 | }, | ||
487 | [1 ... DA850_N_BB_USER_SW] = { | ||
488 | .type = EV_SW, | ||
489 | .active_low = 1, | ||
490 | .wakeup = 0, | ||
491 | .debounce_interval = DA850_KEYS_DEBOUNCE_MS, | ||
492 | .code = -1, /* assigned at runtime */ | ||
493 | .desc = NULL, /* assigned at runtime */ | ||
494 | .gpio = -1, /* assigned at runtime */ | ||
495 | }, | ||
496 | }; | ||
497 | |||
498 | static struct gpio_keys_platform_data da850_evm_bb_keys_pdata = { | ||
499 | .buttons = da850_evm_bb_keys, | ||
500 | .nbuttons = ARRAY_SIZE(da850_evm_bb_keys), | ||
501 | .poll_interval = DA850_GPIO_KEYS_POLL_MS, | ||
502 | }; | ||
503 | |||
504 | static struct platform_device da850_evm_bb_keys_device = { | ||
505 | .name = "gpio-keys-polled", | ||
506 | .id = 1, | ||
507 | .dev = { | ||
508 | .platform_data = &da850_evm_bb_keys_pdata | ||
509 | }, | ||
510 | }; | ||
511 | |||
512 | static void da850_evm_bb_keys_init(unsigned gpio) | ||
513 | { | ||
514 | int i; | ||
515 | struct gpio_keys_button *button; | ||
516 | |||
517 | button = &da850_evm_bb_keys[0]; | ||
518 | button->desc = (char *) | ||
519 | da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_PB1]; | ||
520 | button->gpio = gpio + DA850_EVM_BB_EXP_USER_PB1; | ||
521 | |||
522 | for (i = 0; i < DA850_N_BB_USER_SW; i++) { | ||
523 | button = &da850_evm_bb_keys[i + 1]; | ||
524 | button->code = SW_LID + i; | ||
525 | button->desc = (char *) | ||
526 | da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_SW1 + i]; | ||
527 | button->gpio = gpio + DA850_EVM_BB_EXP_USER_SW1 + i; | ||
528 | } | ||
529 | } | ||
331 | 530 | ||
332 | gpio_free(gpio + 5); | 531 | #define DA850_N_BB_USER_LED 2 |
333 | gpio_free(gpio + 6); | 532 | |
334 | gpio_free(gpio + 7); | 533 | static struct gpio_led da850_evm_bb_leds[] = { |
534 | [0 ... DA850_N_BB_USER_LED - 1] = { | ||
535 | .active_low = 1, | ||
536 | .gpio = -1, /* assigned at runtime */ | ||
537 | .name = NULL, /* assigned at runtime */ | ||
538 | }, | ||
539 | }; | ||
540 | |||
541 | static struct gpio_led_platform_data da850_evm_bb_leds_pdata = { | ||
542 | .leds = da850_evm_bb_leds, | ||
543 | .num_leds = ARRAY_SIZE(da850_evm_bb_leds), | ||
544 | }; | ||
545 | |||
546 | static struct platform_device da850_evm_bb_leds_device = { | ||
547 | .name = "leds-gpio", | ||
548 | .id = -1, | ||
549 | .dev = { | ||
550 | .platform_data = &da850_evm_bb_leds_pdata | ||
551 | } | ||
552 | }; | ||
553 | |||
554 | static void da850_evm_bb_leds_init(unsigned gpio) | ||
555 | { | ||
556 | int i; | ||
557 | struct gpio_led *led; | ||
558 | |||
559 | for (i = 0; i < DA850_N_BB_USER_LED; i++) { | ||
560 | led = &da850_evm_bb_leds[i]; | ||
561 | |||
562 | led->gpio = gpio + DA850_EVM_BB_EXP_USER_LED2 + i; | ||
563 | led->name = | ||
564 | da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_LED2 + i]; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | static int da850_evm_bb_expander_setup(struct i2c_client *client, | ||
569 | unsigned gpio, unsigned ngpio, | ||
570 | void *c) | ||
571 | { | ||
572 | int ret; | ||
573 | |||
574 | /* | ||
575 | * Register the switches and pushbutton on the baseboard as a gpio-keys | ||
576 | * device. | ||
577 | */ | ||
578 | da850_evm_bb_keys_init(gpio); | ||
579 | ret = platform_device_register(&da850_evm_bb_keys_device); | ||
580 | if (ret) { | ||
581 | pr_warning("Could not register baseboard GPIO expander keys"); | ||
582 | goto io_exp_setup_sw_fail; | ||
583 | } | ||
584 | |||
585 | da850_evm_bb_leds_init(gpio); | ||
586 | ret = platform_device_register(&da850_evm_bb_leds_device); | ||
587 | if (ret) { | ||
588 | pr_warning("Could not register baseboard GPIO expander LEDS"); | ||
589 | goto io_exp_setup_leds_fail; | ||
590 | } | ||
591 | |||
592 | return 0; | ||
593 | |||
594 | io_exp_setup_leds_fail: | ||
595 | platform_device_unregister(&da850_evm_bb_keys_device); | ||
596 | io_exp_setup_sw_fail: | ||
597 | return ret; | ||
598 | } | ||
599 | |||
600 | static int da850_evm_bb_expander_teardown(struct i2c_client *client, | ||
601 | unsigned gpio, unsigned ngpio, void *c) | ||
602 | { | ||
603 | platform_device_unregister(&da850_evm_bb_leds_device); | ||
604 | platform_device_unregister(&da850_evm_bb_keys_device); | ||
335 | 605 | ||
336 | return 0; | 606 | return 0; |
337 | } | 607 | } |
@@ -340,6 +610,14 @@ static struct pca953x_platform_data da850_evm_ui_expander_info = { | |||
340 | .gpio_base = DAVINCI_N_GPIO, | 610 | .gpio_base = DAVINCI_N_GPIO, |
341 | .setup = da850_evm_ui_expander_setup, | 611 | .setup = da850_evm_ui_expander_setup, |
342 | .teardown = da850_evm_ui_expander_teardown, | 612 | .teardown = da850_evm_ui_expander_teardown, |
613 | .names = da850_evm_ui_exp, | ||
614 | }; | ||
615 | |||
616 | static struct pca953x_platform_data da850_evm_bb_expander_info = { | ||
617 | .gpio_base = DA850_BB_EXPANDER_GPIO_BASE, | ||
618 | .setup = da850_evm_bb_expander_setup, | ||
619 | .teardown = da850_evm_bb_expander_teardown, | ||
620 | .names = da850_evm_bb_exp, | ||
343 | }; | 621 | }; |
344 | 622 | ||
345 | static struct i2c_board_info __initdata da850_evm_i2c_devices[] = { | 623 | static struct i2c_board_info __initdata da850_evm_i2c_devices[] = { |
@@ -350,6 +628,10 @@ static struct i2c_board_info __initdata da850_evm_i2c_devices[] = { | |||
350 | I2C_BOARD_INFO("tca6416", 0x20), | 628 | I2C_BOARD_INFO("tca6416", 0x20), |
351 | .platform_data = &da850_evm_ui_expander_info, | 629 | .platform_data = &da850_evm_ui_expander_info, |
352 | }, | 630 | }, |
631 | { | ||
632 | I2C_BOARD_INFO("tca6416", 0x21), | ||
633 | .platform_data = &da850_evm_bb_expander_info, | ||
634 | }, | ||
353 | }; | 635 | }; |
354 | 636 | ||
355 | static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = { | 637 | static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = { |
@@ -540,7 +822,7 @@ static struct regulator_init_data tps65070_regulator_data[] = { | |||
540 | { | 822 | { |
541 | .constraints = { | 823 | .constraints = { |
542 | .min_uV = 950000, | 824 | .min_uV = 950000, |
543 | .max_uV = 1320000, | 825 | .max_uV = 1350000, |
544 | .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | | 826 | .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE | |
545 | REGULATOR_CHANGE_STATUS), | 827 | REGULATOR_CHANGE_STATUS), |
546 | .boot_on = 1, | 828 | .boot_on = 1, |
@@ -591,7 +873,7 @@ static struct tps6507x_board tps_board = { | |||
591 | .tps6507x_ts_init_data = &tps6507x_touchscreen_data, | 873 | .tps6507x_ts_init_data = &tps6507x_touchscreen_data, |
592 | }; | 874 | }; |
593 | 875 | ||
594 | static struct i2c_board_info __initdata da850evm_tps65070_info[] = { | 876 | static struct i2c_board_info __initdata da850_evm_tps65070_info[] = { |
595 | { | 877 | { |
596 | I2C_BOARD_INFO("tps6507x", 0x48), | 878 | I2C_BOARD_INFO("tps6507x", 0x48), |
597 | .platform_data = &tps_board, | 879 | .platform_data = &tps_board, |
@@ -600,8 +882,8 @@ static struct i2c_board_info __initdata da850evm_tps65070_info[] = { | |||
600 | 882 | ||
601 | static int __init pmic_tps65070_init(void) | 883 | static int __init pmic_tps65070_init(void) |
602 | { | 884 | { |
603 | return i2c_register_board_info(1, da850evm_tps65070_info, | 885 | return i2c_register_board_info(1, da850_evm_tps65070_info, |
604 | ARRAY_SIZE(da850evm_tps65070_info)); | 886 | ARRAY_SIZE(da850_evm_tps65070_info)); |
605 | } | 887 | } |
606 | 888 | ||
607 | static const short da850_evm_lcdc_pins[] = { | 889 | static const short da850_evm_lcdc_pins[] = { |
@@ -736,6 +1018,27 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { | |||
736 | &da850_edma_cc1_rsv, | 1018 | &da850_edma_cc1_rsv, |
737 | }; | 1019 | }; |
738 | 1020 | ||
1021 | #ifdef CONFIG_CPU_FREQ | ||
1022 | static __init int da850_evm_init_cpufreq(void) | ||
1023 | { | ||
1024 | switch (system_rev & 0xF) { | ||
1025 | case 3: | ||
1026 | da850_max_speed = 456000; | ||
1027 | break; | ||
1028 | case 2: | ||
1029 | da850_max_speed = 408000; | ||
1030 | break; | ||
1031 | case 1: | ||
1032 | da850_max_speed = 372000; | ||
1033 | break; | ||
1034 | } | ||
1035 | |||
1036 | return da850_register_cpufreq("pll0_sysclk3"); | ||
1037 | } | ||
1038 | #else | ||
1039 | static __init int da850_evm_init_cpufreq(void) { return 0; } | ||
1040 | #endif | ||
1041 | |||
739 | static __init void da850_evm_init(void) | 1042 | static __init void da850_evm_init(void) |
740 | { | 1043 | { |
741 | int ret; | 1044 | int ret; |
@@ -836,7 +1139,7 @@ static __init void da850_evm_init(void) | |||
836 | if (ret) | 1139 | if (ret) |
837 | pr_warning("da850_evm_init: rtc setup failed: %d\n", ret); | 1140 | pr_warning("da850_evm_init: rtc setup failed: %d\n", ret); |
838 | 1141 | ||
839 | ret = da850_register_cpufreq("pll0_sysclk3"); | 1142 | ret = da850_evm_init_cpufreq(); |
840 | if (ret) | 1143 | if (ret) |
841 | pr_warning("da850_evm_init: cpufreq registration failed: %d\n", | 1144 | pr_warning("da850_evm_init: cpufreq registration failed: %d\n", |
842 | ret); | 1145 | ret); |
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 01ba080433db..e4e3af179f02 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c | |||
@@ -336,7 +336,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate) | |||
336 | ratio--; | 336 | ratio--; |
337 | } | 337 | } |
338 | 338 | ||
339 | if (ratio > PLLDIV_RATIO_MASK) | 339 | if (ratio > pll->div_ratio_mask) |
340 | return -EINVAL; | 340 | return -EINVAL; |
341 | 341 | ||
342 | do { | 342 | do { |
@@ -344,7 +344,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate) | |||
344 | } while (v & PLLSTAT_GOSTAT); | 344 | } while (v & PLLSTAT_GOSTAT); |
345 | 345 | ||
346 | v = __raw_readl(pll->base + clk->div_reg); | 346 | v = __raw_readl(pll->base + clk->div_reg); |
347 | v &= ~PLLDIV_RATIO_MASK; | 347 | v &= ~pll->div_ratio_mask; |
348 | v |= ratio | PLLDIV_EN; | 348 | v |= ratio | PLLDIV_EN; |
349 | __raw_writel(v, pll->base + clk->div_reg); | 349 | __raw_writel(v, pll->base + clk->div_reg); |
350 | 350 | ||
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b902760..78b5ae29ae40 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c | |||
@@ -830,8 +830,7 @@ static void da850_set_async3_src(int pllnum) | |||
830 | * According to the TRM, minimum PLLM results in maximum power savings. | 830 | * According to the TRM, minimum PLLM results in maximum power savings. |
831 | * The OPP definitions below should keep the PLLM as low as possible. | 831 | * The OPP definitions below should keep the PLLM as low as possible. |
832 | * | 832 | * |
833 | * The output of the PLLM must be between 400 to 600 MHz. | 833 | * The output of the PLLM must be between 300 to 600 MHz. |
834 | * This rules out prediv of anything but divide-by-one for 24Mhz OSC input. | ||
835 | */ | 834 | */ |
836 | struct da850_opp { | 835 | struct da850_opp { |
837 | unsigned int freq; /* in KHz */ | 836 | unsigned int freq; /* in KHz */ |
@@ -842,6 +841,33 @@ struct da850_opp { | |||
842 | unsigned int cvdd_max; /* in uV */ | 841 | unsigned int cvdd_max; /* in uV */ |
843 | }; | 842 | }; |
844 | 843 | ||
844 | static const struct da850_opp da850_opp_456 = { | ||
845 | .freq = 456000, | ||
846 | .prediv = 1, | ||
847 | .mult = 19, | ||
848 | .postdiv = 1, | ||
849 | .cvdd_min = 1300000, | ||
850 | .cvdd_max = 1350000, | ||
851 | }; | ||
852 | |||
853 | static const struct da850_opp da850_opp_408 = { | ||
854 | .freq = 408000, | ||
855 | .prediv = 1, | ||
856 | .mult = 17, | ||
857 | .postdiv = 1, | ||
858 | .cvdd_min = 1300000, | ||
859 | .cvdd_max = 1350000, | ||
860 | }; | ||
861 | |||
862 | static const struct da850_opp da850_opp_372 = { | ||
863 | .freq = 372000, | ||
864 | .prediv = 2, | ||
865 | .mult = 31, | ||
866 | .postdiv = 1, | ||
867 | .cvdd_min = 1200000, | ||
868 | .cvdd_max = 1320000, | ||
869 | }; | ||
870 | |||
845 | static const struct da850_opp da850_opp_300 = { | 871 | static const struct da850_opp da850_opp_300 = { |
846 | .freq = 300000, | 872 | .freq = 300000, |
847 | .prediv = 1, | 873 | .prediv = 1, |
@@ -876,6 +902,9 @@ static const struct da850_opp da850_opp_96 = { | |||
876 | } | 902 | } |
877 | 903 | ||
878 | static struct cpufreq_frequency_table da850_freq_table[] = { | 904 | static struct cpufreq_frequency_table da850_freq_table[] = { |
905 | OPP(456), | ||
906 | OPP(408), | ||
907 | OPP(372), | ||
879 | OPP(300), | 908 | OPP(300), |
880 | OPP(200), | 909 | OPP(200), |
881 | OPP(96), | 910 | OPP(96), |
@@ -886,6 +915,19 @@ static struct cpufreq_frequency_table da850_freq_table[] = { | |||
886 | }; | 915 | }; |
887 | 916 | ||
888 | #ifdef CONFIG_REGULATOR | 917 | #ifdef CONFIG_REGULATOR |
918 | static int da850_set_voltage(unsigned int index); | ||
919 | static int da850_regulator_init(void); | ||
920 | #endif | ||
921 | |||
922 | static struct davinci_cpufreq_config cpufreq_info = { | ||
923 | .freq_table = da850_freq_table, | ||
924 | #ifdef CONFIG_REGULATOR | ||
925 | .init = da850_regulator_init, | ||
926 | .set_voltage = da850_set_voltage, | ||
927 | #endif | ||
928 | }; | ||
929 | |||
930 | #ifdef CONFIG_REGULATOR | ||
889 | static struct regulator *cvdd; | 931 | static struct regulator *cvdd; |
890 | 932 | ||
891 | static int da850_set_voltage(unsigned int index) | 933 | static int da850_set_voltage(unsigned int index) |
@@ -895,7 +937,7 @@ static int da850_set_voltage(unsigned int index) | |||
895 | if (!cvdd) | 937 | if (!cvdd) |
896 | return -ENODEV; | 938 | return -ENODEV; |
897 | 939 | ||
898 | opp = (struct da850_opp *) da850_freq_table[index].index; | 940 | opp = (struct da850_opp *) cpufreq_info.freq_table[index].index; |
899 | 941 | ||
900 | return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max); | 942 | return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max); |
901 | } | 943 | } |
@@ -912,14 +954,6 @@ static int da850_regulator_init(void) | |||
912 | } | 954 | } |
913 | #endif | 955 | #endif |
914 | 956 | ||
915 | static struct davinci_cpufreq_config cpufreq_info = { | ||
916 | .freq_table = &da850_freq_table[0], | ||
917 | #ifdef CONFIG_REGULATOR | ||
918 | .init = da850_regulator_init, | ||
919 | .set_voltage = da850_set_voltage, | ||
920 | #endif | ||
921 | }; | ||
922 | |||
923 | static struct platform_device da850_cpufreq_device = { | 957 | static struct platform_device da850_cpufreq_device = { |
924 | .name = "cpufreq-davinci", | 958 | .name = "cpufreq-davinci", |
925 | .dev = { | 959 | .dev = { |
@@ -928,12 +962,22 @@ static struct platform_device da850_cpufreq_device = { | |||
928 | .id = -1, | 962 | .id = -1, |
929 | }; | 963 | }; |
930 | 964 | ||
965 | unsigned int da850_max_speed = 300000; | ||
966 | |||
931 | int __init da850_register_cpufreq(char *async_clk) | 967 | int __init da850_register_cpufreq(char *async_clk) |
932 | { | 968 | { |
969 | int i; | ||
970 | |||
933 | /* cpufreq driver can help keep an "async" clock constant */ | 971 | /* cpufreq driver can help keep an "async" clock constant */ |
934 | if (async_clk) | 972 | if (async_clk) |
935 | clk_add_alias("async", da850_cpufreq_device.name, | 973 | clk_add_alias("async", da850_cpufreq_device.name, |
936 | async_clk, NULL); | 974 | async_clk, NULL); |
975 | for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) { | ||
976 | if (da850_freq_table[i].frequency <= da850_max_speed) { | ||
977 | cpufreq_info.freq_table = &da850_freq_table[i]; | ||
978 | break; | ||
979 | } | ||
980 | } | ||
937 | 981 | ||
938 | return platform_device_register(&da850_cpufreq_device); | 982 | return platform_device_register(&da850_cpufreq_device); |
939 | } | 983 | } |
@@ -942,17 +986,18 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate) | |||
942 | { | 986 | { |
943 | int i, ret = 0, diff; | 987 | int i, ret = 0, diff; |
944 | unsigned int best = (unsigned int) -1; | 988 | unsigned int best = (unsigned int) -1; |
989 | struct cpufreq_frequency_table *table = cpufreq_info.freq_table; | ||
945 | 990 | ||
946 | rate /= 1000; /* convert to kHz */ | 991 | rate /= 1000; /* convert to kHz */ |
947 | 992 | ||
948 | for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { | 993 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { |
949 | diff = da850_freq_table[i].frequency - rate; | 994 | diff = table[i].frequency - rate; |
950 | if (diff < 0) | 995 | if (diff < 0) |
951 | diff = -diff; | 996 | diff = -diff; |
952 | 997 | ||
953 | if (diff < best) { | 998 | if (diff < best) { |
954 | best = diff; | 999 | best = diff; |
955 | ret = da850_freq_table[i].frequency; | 1000 | ret = table[i].frequency; |
956 | } | 1001 | } |
957 | } | 1002 | } |
958 | 1003 | ||
@@ -973,7 +1018,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index) | |||
973 | struct pll_data *pll = clk->pll_data; | 1018 | struct pll_data *pll = clk->pll_data; |
974 | int ret; | 1019 | int ret; |
975 | 1020 | ||
976 | opp = (struct da850_opp *) da850_freq_table[index].index; | 1021 | opp = (struct da850_opp *) cpufreq_info.freq_table[index].index; |
977 | prediv = opp->prediv; | 1022 | prediv = opp->prediv; |
978 | mult = opp->mult; | 1023 | mult = opp->mult; |
979 | postdiv = opp->postdiv; | 1024 | postdiv = opp->postdiv; |
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index c9a86d8130d1..85503debda51 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c | |||
@@ -344,7 +344,20 @@ static struct platform_device tsc_device = { | |||
344 | 344 | ||
345 | void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) | 345 | void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) |
346 | { | 346 | { |
347 | int i; | 347 | int i, error; |
348 | struct clk *tsc_clk; | ||
349 | |||
350 | /* | ||
351 | * The reset defaults for tnetv107x tsc clock divider is set too high. | ||
352 | * This forces the clock down to a range that allows the ADC to | ||
353 | * complete sample conversion in time. | ||
354 | */ | ||
355 | tsc_clk = clk_get(NULL, "sys_tsc_clk"); | ||
356 | if (tsc_clk) { | ||
357 | error = clk_set_rate(tsc_clk, 5000000); | ||
358 | WARN_ON(error < 0); | ||
359 | clk_put(tsc_clk); | ||
360 | } | ||
348 | 361 | ||
349 | platform_device_register(&edma_device); | 362 | platform_device_register(&edma_device); |
350 | platform_device_register(&tnetv107x_wdt_device); | 363 | platform_device_register(&tnetv107x_wdt_device); |
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 4247b3f53b33..e7f952066527 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h | |||
@@ -28,6 +28,13 @@ extern void __iomem *da8xx_syscfg0_base; | |||
28 | extern void __iomem *da8xx_syscfg1_base; | 28 | extern void __iomem *da8xx_syscfg1_base; |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * If the DA850/OMAP-L138/AM18x SoC on board is of a higher speed grade | ||
32 | * (than the regular 300Mhz variant), the board code should set this up | ||
33 | * with the supported speed before calling da850_register_cpufreq(). | ||
34 | */ | ||
35 | extern unsigned int da850_max_speed; | ||
36 | |||
37 | /* | ||
31 | * The cp_intc interrupt controller for the da8xx isn't in the same | 38 | * The cp_intc interrupt controller for the da8xx isn't in the same |
32 | * chunk of physical memory space as the other registers (like it is | 39 | * chunk of physical memory space as the other registers (like it is |
33 | * on the davincis) so it needs to be mapped separately. It will be | 40 | * on the davincis) so it needs to be mapped separately. It will be |
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index 1b15dbd0a77b..a41580400701 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c | |||
@@ -83,21 +83,16 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, | |||
83 | pdctl1 = __raw_readl(psc_base + PDCTL1); | 83 | pdctl1 = __raw_readl(psc_base + PDCTL1); |
84 | pdctl1 |= 0x100; | 84 | pdctl1 |= 0x100; |
85 | __raw_writel(pdctl1, psc_base + PDCTL1); | 85 | __raw_writel(pdctl1, psc_base + PDCTL1); |
86 | |||
87 | do { | ||
88 | ptstat = __raw_readl(psc_base + | ||
89 | PTSTAT); | ||
90 | } while (!(((ptstat >> domain) & 1) == 0)); | ||
91 | } else { | 86 | } else { |
92 | ptcmd = 1 << domain; | 87 | ptcmd = 1 << domain; |
93 | __raw_writel(ptcmd, psc_base + PTCMD); | 88 | __raw_writel(ptcmd, psc_base + PTCMD); |
94 | |||
95 | do { | ||
96 | ptstat = __raw_readl(psc_base + PTSTAT); | ||
97 | } while (!(((ptstat >> domain) & 1) == 0)); | ||
98 | } | 89 | } |
99 | 90 | ||
100 | do { | 91 | do { |
92 | ptstat = __raw_readl(psc_base + PTSTAT); | ||
93 | } while (!(((ptstat >> domain) & 1) == 0)); | ||
94 | |||
95 | do { | ||
101 | mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); | 96 | mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); |
102 | } while (!((mdstat & MDSTAT_STATE_MASK) == next_state)); | 97 | } while (!((mdstat & MDSTAT_STATE_MASK) == next_state)); |
103 | 98 | ||
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 0f21c36e65dd..5d1eea026635 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c | |||
@@ -272,15 +272,36 @@ static cycle_t read_cycles(struct clocksource *cs) | |||
272 | return (cycles_t)timer32_read(t); | 272 | return (cycles_t)timer32_read(t); |
273 | } | 273 | } |
274 | 274 | ||
275 | /* | ||
276 | * Kernel assumes that sched_clock can be called early but may not have | ||
277 | * things ready yet. | ||
278 | */ | ||
279 | static cycle_t read_dummy(struct clocksource *cs) | ||
280 | { | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | |||
275 | static struct clocksource clocksource_davinci = { | 285 | static struct clocksource clocksource_davinci = { |
276 | .rating = 300, | 286 | .rating = 300, |
277 | .read = read_cycles, | 287 | .read = read_dummy, |
278 | .mask = CLOCKSOURCE_MASK(32), | 288 | .mask = CLOCKSOURCE_MASK(32), |
279 | .shift = 24, | 289 | .shift = 24, |
280 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 290 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
281 | }; | 291 | }; |
282 | 292 | ||
283 | /* | 293 | /* |
294 | * Overwrite weak default sched_clock with something more precise | ||
295 | */ | ||
296 | unsigned long long notrace sched_clock(void) | ||
297 | { | ||
298 | const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); | ||
299 | |||
300 | return clocksource_cyc2ns(cyc, clocksource_davinci.mult, | ||
301 | clocksource_davinci.shift); | ||
302 | } | ||
303 | |||
304 | /* | ||
284 | * clockevent | 305 | * clockevent |
285 | */ | 306 | */ |
286 | static int davinci_set_next_event(unsigned long cycles, | 307 | static int davinci_set_next_event(unsigned long cycles, |
@@ -377,6 +398,7 @@ static void __init davinci_timer_init(void) | |||
377 | davinci_clock_tick_rate = clk_get_rate(timer_clk); | 398 | davinci_clock_tick_rate = clk_get_rate(timer_clk); |
378 | 399 | ||
379 | /* setup clocksource */ | 400 | /* setup clocksource */ |
401 | clocksource_davinci.read = read_cycles; | ||
380 | clocksource_davinci.name = id_to_name[clocksource_id]; | 402 | clocksource_davinci.name = id_to_name[clocksource_id]; |
381 | clocksource_davinci.mult = | 403 | clocksource_davinci.mult = |
382 | clocksource_khz2mult(davinci_clock_tick_rate/1000, | 404 | clocksource_khz2mult(davinci_clock_tick_rate/1000, |
diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index daeae06430b9..6fcdecec8d8c 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c | |||
@@ -131,12 +131,13 @@ define_pll_clk(tdm, 1, 0x0ff, 0x200); | |||
131 | define_pll_clk(eth, 2, 0x0ff, 0x400); | 131 | define_pll_clk(eth, 2, 0x0ff, 0x400); |
132 | 132 | ||
133 | /* Level 2 - divided outputs from the PLLs */ | 133 | /* Level 2 - divided outputs from the PLLs */ |
134 | #define define_pll_div_clk(pll, cname, div) \ | 134 | #define define_pll_div_clk(pll, cname, div) \ |
135 | static struct clk pll##_##cname##_clk = { \ | 135 | static struct clk pll##_##cname##_clk = { \ |
136 | .name = #pll "_" #cname "_clk",\ | 136 | .name = #pll "_" #cname "_clk", \ |
137 | .parent = &pll_##pll##_clk, \ | 137 | .parent = &pll_##pll##_clk, \ |
138 | .flags = CLK_PLL, \ | 138 | .flags = CLK_PLL, \ |
139 | .div_reg = PLLDIV##div, \ | 139 | .div_reg = PLLDIV##div, \ |
140 | .set_rate = davinci_set_sysclk_rate, \ | ||
140 | } | 141 | } |
141 | 142 | ||
142 | define_pll_div_clk(sys, arm1176, 1); | 143 | define_pll_div_clk(sys, arm1176, 1); |
@@ -192,6 +193,7 @@ lpsc_clk_enabled(system, sys_half_clk, SYSTEM); | |||
192 | lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST); | 193 | lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST); |
193 | lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST); | 194 | lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST); |
194 | lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM); | 195 | lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM); |
196 | lpsc_clk_enabled(timer1, sys_half_clk, TIMER1); | ||
195 | 197 | ||
196 | lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE); | 198 | lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE); |
197 | lpsc_clk(ethss, eth_125mhz_clk, ETHSS); | 199 | lpsc_clk(ethss, eth_125mhz_clk, ETHSS); |
@@ -205,16 +207,15 @@ lpsc_clk(mdio, sys_half_clk, MDIO); | |||
205 | lpsc_clk(sdio0, sys_half_clk, SDIO0); | 207 | lpsc_clk(sdio0, sys_half_clk, SDIO0); |
206 | lpsc_clk(sdio1, sys_half_clk, SDIO1); | 208 | lpsc_clk(sdio1, sys_half_clk, SDIO1); |
207 | lpsc_clk(timer0, sys_half_clk, TIMER0); | 209 | lpsc_clk(timer0, sys_half_clk, TIMER0); |
208 | lpsc_clk(timer1, sys_half_clk, TIMER1); | ||
209 | lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP); | 210 | lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP); |
210 | lpsc_clk(ssp, sys_half_clk, SSP); | 211 | lpsc_clk(ssp, sys_half_clk, SSP); |
211 | lpsc_clk(tdm0, tdm_0_clk, TDM0); | 212 | lpsc_clk(tdm0, tdm_0_clk, TDM0); |
212 | lpsc_clk(tdm1, tdm_1_clk, TDM1); | 213 | lpsc_clk(tdm1, tdm_1_clk, TDM1); |
213 | lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ); | 214 | lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ); |
214 | lpsc_clk(mcdma, sys_half_clk, MCDMA); | 215 | lpsc_clk(mcdma, sys_half_clk, MCDMA); |
215 | lpsc_clk(usb0, sys_half_clk, USB0); | ||
216 | lpsc_clk(usb1, sys_half_clk, USB1); | ||
217 | lpsc_clk(usbss, sys_half_clk, USBSS); | 216 | lpsc_clk(usbss, sys_half_clk, USBSS); |
217 | lpsc_clk(usb0, clk_usbss, USB0); | ||
218 | lpsc_clk(usb1, clk_usbss, USB1); | ||
218 | lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII); | 219 | lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII); |
219 | lpsc_clk(imcop, sys_dsp_clk, IMCOP); | 220 | lpsc_clk(imcop, sys_dsp_clk, IMCOP); |
220 | lpsc_clk(spare, sys_half_clk, SPARE); | 221 | lpsc_clk(spare, sys_half_clk, SPARE); |
@@ -281,7 +282,9 @@ static struct clk_lookup clks[] = { | |||
281 | CLK(NULL, "clk_tdm0", &clk_tdm0), | 282 | CLK(NULL, "clk_tdm0", &clk_tdm0), |
282 | CLK(NULL, "clk_vlynq", &clk_vlynq), | 283 | CLK(NULL, "clk_vlynq", &clk_vlynq), |
283 | CLK(NULL, "clk_mcdma", &clk_mcdma), | 284 | CLK(NULL, "clk_mcdma", &clk_mcdma), |
285 | CLK(NULL, "clk_usbss", &clk_usbss), | ||
284 | CLK(NULL, "clk_usb0", &clk_usb0), | 286 | CLK(NULL, "clk_usb0", &clk_usb0), |
287 | CLK(NULL, "clk_usb1", &clk_usb1), | ||
285 | CLK(NULL, "clk_tdm1", &clk_tdm1), | 288 | CLK(NULL, "clk_tdm1", &clk_tdm1), |
286 | CLK(NULL, "clk_debugss", &clk_debugss), | 289 | CLK(NULL, "clk_debugss", &clk_debugss), |
287 | CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii), | 290 | CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii), |
@@ -289,8 +292,6 @@ static struct clk_lookup clks[] = { | |||
289 | CLK(NULL, "clk_imcop", &clk_imcop), | 292 | CLK(NULL, "clk_imcop", &clk_imcop), |
290 | CLK(NULL, "clk_spare", &clk_spare), | 293 | CLK(NULL, "clk_spare", &clk_spare), |
291 | CLK("davinci_mmc.1", NULL, &clk_sdio1), | 294 | CLK("davinci_mmc.1", NULL, &clk_sdio1), |
292 | CLK(NULL, "clk_usb1", &clk_usb1), | ||
293 | CLK(NULL, "clk_usbss", &clk_usbss), | ||
294 | CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst), | 295 | CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst), |
295 | CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst), | 296 | CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst), |
296 | CLK(NULL, NULL, NULL), | 297 | CLK(NULL, NULL, NULL), |
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig index 3b9a32ace909..a4ed3900912a 100644 --- a/arch/arm/mach-dove/Kconfig +++ b/arch/arm/mach-dove/Kconfig | |||
@@ -9,6 +9,12 @@ config MACH_DOVE_DB | |||
9 | Say 'Y' here if you want your kernel to support the | 9 | Say 'Y' here if you want your kernel to support the |
10 | Marvell DB-MV88AP510 Development Board. | 10 | Marvell DB-MV88AP510 Development Board. |
11 | 11 | ||
12 | config MACH_CM_A510 | ||
13 | bool "CompuLab CM-A510 Board" | ||
14 | help | ||
15 | Say 'Y' here if you want your kernel to support the | ||
16 | CompuLab CM-A510 Board. | ||
17 | |||
12 | endmenu | 18 | endmenu |
13 | 19 | ||
14 | endif | 20 | endif |
diff --git a/arch/arm/mach-dove/Makefile b/arch/arm/mach-dove/Makefile index 7ab3be53f642..fa0f01856060 100644 --- a/arch/arm/mach-dove/Makefile +++ b/arch/arm/mach-dove/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-y += common.o addr-map.o irq.o pcie.o | 1 | obj-y += common.o addr-map.o irq.o pcie.o mpp.o |
2 | 2 | ||
3 | obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o | 3 | obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o |
4 | obj-$(CONFIG_MACH_CM_A510) += cm-a510.o | ||
diff --git a/arch/arm/mach-dove/cm-a510.c b/arch/arm/mach-dove/cm-a510.c new file mode 100644 index 000000000000..96e0e94e5fa9 --- /dev/null +++ b/arch/arm/mach-dove/cm-a510.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-dove/cm-a510.c | ||
3 | * | ||
4 | * Copyright (C) 2010 CompuLab, Ltd. | ||
5 | * Konstantin Sinyuk <kostyas@compulab.co.il> | ||
6 | * | ||
7 | * Based on Marvell DB-MV88AP510-BP Development Board Setup | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/ata_platform.h> | ||
18 | #include <linux/mv643xx_eth.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | #include <linux/spi/flash.h> | ||
21 | |||
22 | #include <asm/mach-types.h> | ||
23 | #include <asm/mach/arch.h> | ||
24 | |||
25 | #include <mach/dove.h> | ||
26 | |||
27 | #include "common.h" | ||
28 | |||
29 | static struct mv643xx_eth_platform_data cm_a510_ge00_data = { | ||
30 | .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT, | ||
31 | }; | ||
32 | |||
33 | static struct mv_sata_platform_data cm_a510_sata_data = { | ||
34 | .n_ports = 1, | ||
35 | }; | ||
36 | |||
37 | /* | ||
38 | * SPI Devices: | ||
39 | * SPI0: 1M Flash Winbond w25q32bv | ||
40 | */ | ||
41 | static const struct flash_platform_data cm_a510_spi_flash_data = { | ||
42 | .type = "w25q32bv", | ||
43 | }; | ||
44 | |||
45 | static struct spi_board_info __initdata cm_a510_spi_flash_info[] = { | ||
46 | { | ||
47 | .modalias = "m25p80", | ||
48 | .platform_data = &cm_a510_spi_flash_data, | ||
49 | .irq = -1, | ||
50 | .max_speed_hz = 20000000, | ||
51 | .bus_num = 0, | ||
52 | .chip_select = 0, | ||
53 | }, | ||
54 | }; | ||
55 | |||
56 | static int __init cm_a510_pci_init(void) | ||
57 | { | ||
58 | if (machine_is_cm_a510()) | ||
59 | dove_pcie_init(1, 1); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | subsys_initcall(cm_a510_pci_init); | ||
65 | |||
66 | /* Board Init */ | ||
67 | static void __init cm_a510_init(void) | ||
68 | { | ||
69 | /* | ||
70 | * Basic Dove setup. Needs to be called early. | ||
71 | */ | ||
72 | dove_init(); | ||
73 | |||
74 | dove_ge00_init(&cm_a510_ge00_data); | ||
75 | dove_ehci0_init(); | ||
76 | dove_ehci1_init(); | ||
77 | dove_sata_init(&cm_a510_sata_data); | ||
78 | dove_sdio0_init(); | ||
79 | dove_sdio1_init(); | ||
80 | dove_spi0_init(); | ||
81 | dove_spi1_init(); | ||
82 | dove_uart0_init(); | ||
83 | dove_uart1_init(); | ||
84 | dove_i2c_init(); | ||
85 | spi_register_board_info(cm_a510_spi_flash_info, | ||
86 | ARRAY_SIZE(cm_a510_spi_flash_info)); | ||
87 | } | ||
88 | |||
89 | MACHINE_START(CM_A510, "Compulab CM-A510 Board") | ||
90 | .boot_params = 0x00000100, | ||
91 | .init_machine = cm_a510_init, | ||
92 | .map_io = dove_map_io, | ||
93 | .init_irq = dove_init_irq, | ||
94 | .timer = &dove_timer, | ||
95 | MACHINE_END | ||
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h index f6a08397f046..27b414578f2e 100644 --- a/arch/arm/mach-dove/include/mach/dove.h +++ b/arch/arm/mach-dove/include/mach/dove.h | |||
@@ -131,14 +131,21 @@ | |||
131 | #define DOVE_RESET_SAMPLE_LO (DOVE_MPP_VIRT_BASE | 0x014) | 131 | #define DOVE_RESET_SAMPLE_LO (DOVE_MPP_VIRT_BASE | 0x014) |
132 | #define DOVE_RESET_SAMPLE_HI (DOVE_MPP_VIRT_BASE | 0x018) | 132 | #define DOVE_RESET_SAMPLE_HI (DOVE_MPP_VIRT_BASE | 0x018) |
133 | #define DOVE_GPIO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400) | 133 | #define DOVE_GPIO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400) |
134 | #define DOVE_GPIO2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe8400) | ||
134 | #define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c) | 135 | #define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c) |
135 | #define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1) | 136 | #define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1) |
136 | #define DOVE_NAND_GPIO_EN (1 << 0) | 137 | #define DOVE_NAND_GPIO_EN (1 << 0) |
137 | #define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_VIRT_BASE + 0x40) | 138 | #define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_VIRT_BASE + 0x40) |
138 | 139 | #define DOVE_SPI_GPIO_SEL (1 << 5) | |
140 | #define DOVE_UART1_GPIO_SEL (1 << 4) | ||
141 | #define DOVE_AU1_GPIO_SEL (1 << 3) | ||
142 | #define DOVE_CAM_GPIO_SEL (1 << 2) | ||
143 | #define DOVE_SD1_GPIO_SEL (1 << 1) | ||
144 | #define DOVE_SD0_GPIO_SEL (1 << 0) | ||
139 | 145 | ||
140 | /* Power Management */ | 146 | /* Power Management */ |
141 | #define DOVE_PMU_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0000) | 147 | #define DOVE_PMU_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0000) |
148 | #define DOVE_PMU_SIG_CTRL (DOVE_PMU_VIRT_BASE + 0x802c) | ||
142 | 149 | ||
143 | /* Real Time Clock */ | 150 | /* Real Time Clock */ |
144 | #define DOVE_RTC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xd8500) | 151 | #define DOVE_RTC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xd8500) |
diff --git a/arch/arm/mach-dove/include/mach/gpio.h b/arch/arm/mach-dove/include/mach/gpio.h index 0ee70ff39e11..340bb7af529d 100644 --- a/arch/arm/mach-dove/include/mach/gpio.h +++ b/arch/arm/mach-dove/include/mach/gpio.h | |||
@@ -14,12 +14,14 @@ | |||
14 | #include <plat/gpio.h> | 14 | #include <plat/gpio.h> |
15 | #include <asm-generic/gpio.h> /* cansleep wrappers */ | 15 | #include <asm-generic/gpio.h> /* cansleep wrappers */ |
16 | 16 | ||
17 | #define GPIO_MAX 64 | 17 | #define GPIO_MAX 72 |
18 | 18 | ||
19 | #define GPIO_BASE_LO (DOVE_GPIO_VIRT_BASE + 0x00) | 19 | #define GPIO_BASE_LO (DOVE_GPIO_VIRT_BASE + 0x00) |
20 | #define GPIO_BASE_HI (DOVE_GPIO_VIRT_BASE + 0x20) | 20 | #define GPIO_BASE_HI (DOVE_GPIO_VIRT_BASE + 0x20) |
21 | 21 | ||
22 | #define GPIO_BASE(pin) ((pin < 32) ? GPIO_BASE_LO : GPIO_BASE_HI) | 22 | #define GPIO_BASE(pin) ((pin < 32) ? GPIO_BASE_LO : \ |
23 | ((pin < 64) ? GPIO_BASE_HI : \ | ||
24 | DOVE_GPIO2_VIRT_BASE)) | ||
23 | 25 | ||
24 | #define GPIO_OUT(pin) (GPIO_BASE(pin) + 0x00) | 26 | #define GPIO_OUT(pin) (GPIO_BASE(pin) + 0x00) |
25 | #define GPIO_IO_CONF(pin) (GPIO_BASE(pin) + 0x04) | 27 | #define GPIO_IO_CONF(pin) (GPIO_BASE(pin) + 0x04) |
diff --git a/arch/arm/mach-dove/mpp.c b/arch/arm/mach-dove/mpp.c new file mode 100644 index 000000000000..71db2bdf2f28 --- /dev/null +++ b/arch/arm/mach-dove/mpp.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-dove/mpp.c | ||
3 | * | ||
4 | * MPP functions for Marvell Dove SoCs | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/io.h> | ||
14 | |||
15 | #include <mach/dove.h> | ||
16 | |||
17 | #include "mpp.h" | ||
18 | |||
19 | #define MPP_NR_REGS 4 | ||
20 | #define MPP_CTRL(i) ((i) == 3 ? \ | ||
21 | DOVE_MPP_CTRL4_VIRT_BASE : \ | ||
22 | DOVE_MPP_VIRT_BASE + (i) * 4) | ||
23 | #define PMU_SIG_REGS 2 | ||
24 | #define PMU_SIG_CTRL(i) (DOVE_PMU_SIG_CTRL + (i) * 4) | ||
25 | |||
26 | struct dove_mpp_grp { | ||
27 | int start; | ||
28 | int end; | ||
29 | }; | ||
30 | |||
31 | static struct dove_mpp_grp dove_mpp_grp[] = { | ||
32 | [MPP_24_39] = { | ||
33 | .start = 24, | ||
34 | .end = 39, | ||
35 | }, | ||
36 | [MPP_40_45] = { | ||
37 | .start = 40, | ||
38 | .end = 45, | ||
39 | }, | ||
40 | [MPP_46_51] = { | ||
41 | .start = 40, | ||
42 | .end = 45, | ||
43 | }, | ||
44 | [MPP_58_61] = { | ||
45 | .start = 58, | ||
46 | .end = 61, | ||
47 | }, | ||
48 | [MPP_62_63] = { | ||
49 | .start = 62, | ||
50 | .end = 63, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static void dove_mpp_gpio_mode(int start, int end, int gpio_mode) | ||
55 | { | ||
56 | int i; | ||
57 | |||
58 | for (i = start; i <= end; i++) | ||
59 | orion_gpio_set_valid(i, gpio_mode); | ||
60 | } | ||
61 | |||
62 | static void dove_mpp_dump_regs(void) | ||
63 | { | ||
64 | #ifdef DEBUG | ||
65 | int i; | ||
66 | |||
67 | pr_debug("MPP_CTRL regs:"); | ||
68 | for (i = 0; i < MPP_NR_REGS; i++) | ||
69 | printk(" %08x", readl(MPP_CTRL(i))); | ||
70 | printk("\n"); | ||
71 | |||
72 | pr_debug("PMU_SIG_CTRL regs:"); | ||
73 | for (i = 0; i < PMU_SIG_REGS; i++) | ||
74 | printk(" %08x", readl(PMU_SIG_CTRL(i))); | ||
75 | printk("\n"); | ||
76 | |||
77 | pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n", readl(DOVE_PMU_MPP_GENERAL_CTRL)); | ||
78 | pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE)); | ||
79 | #endif | ||
80 | } | ||
81 | |||
82 | static void dove_mpp_cfg_nfc(int sel) | ||
83 | { | ||
84 | u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
85 | |||
86 | mpp_gen_cfg &= ~0x1; | ||
87 | mpp_gen_cfg |= sel; | ||
88 | writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE); | ||
89 | |||
90 | dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK); | ||
91 | } | ||
92 | |||
93 | static void dove_mpp_cfg_au1(int sel) | ||
94 | { | ||
95 | u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | ||
96 | u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1); | ||
97 | u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
98 | u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2); | ||
99 | |||
100 | mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL); | ||
101 | ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1); | ||
102 | mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN); | ||
103 | global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO); | ||
104 | |||
105 | if (!sel || sel == 0x2) | ||
106 | dove_mpp_gpio_mode(52, 57, 0); | ||
107 | else | ||
108 | dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK); | ||
109 | |||
110 | if (sel & 0x1) { | ||
111 | global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO; | ||
112 | dove_mpp_gpio_mode(56, 57, 0); | ||
113 | } | ||
114 | if (sel & 0x2) { | ||
115 | mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN; | ||
116 | dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK); | ||
117 | } | ||
118 | if (sel & 0x4) { | ||
119 | ssp_ctrl1 |= DOVE_SSP_ON_AU1; | ||
120 | dove_mpp_gpio_mode(52, 55, 0); | ||
121 | } | ||
122 | if (sel & 0x8) | ||
123 | mpp_ctrl4 |= DOVE_AU1_GPIO_SEL; | ||
124 | |||
125 | writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE); | ||
126 | writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1); | ||
127 | writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE); | ||
128 | writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2); | ||
129 | } | ||
130 | |||
131 | static void dove_mpp_conf_grp(int num, int sel, u32 *mpp_ctrl) | ||
132 | { | ||
133 | int start = dove_mpp_grp[num].start; | ||
134 | int end = dove_mpp_grp[num].end; | ||
135 | int gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0; | ||
136 | |||
137 | *mpp_ctrl &= ~(0x1 << num); | ||
138 | *mpp_ctrl |= sel << num; | ||
139 | |||
140 | dove_mpp_gpio_mode(start, end, gpio_mode); | ||
141 | } | ||
142 | |||
143 | void __init dove_mpp_conf(unsigned int *mpp_list) | ||
144 | { | ||
145 | u32 mpp_ctrl[MPP_NR_REGS]; | ||
146 | u32 pmu_mpp_ctrl = 0; | ||
147 | u32 pmu_sig_ctrl[PMU_SIG_REGS]; | ||
148 | int i; | ||
149 | |||
150 | /* Initialize gpiolib. */ | ||
151 | orion_gpio_init(); | ||
152 | |||
153 | for (i = 0; i < MPP_NR_REGS; i++) | ||
154 | mpp_ctrl[i] = readl(MPP_CTRL(i)); | ||
155 | |||
156 | for (i = 0; i < PMU_SIG_REGS; i++) | ||
157 | pmu_sig_ctrl[i] = readl(PMU_SIG_CTRL(i)); | ||
158 | |||
159 | pmu_mpp_ctrl = readl(DOVE_PMU_MPP_GENERAL_CTRL); | ||
160 | |||
161 | dove_mpp_dump_regs(); | ||
162 | |||
163 | for ( ; *mpp_list != MPP_END; mpp_list++) { | ||
164 | unsigned int num = MPP_NUM(*mpp_list); | ||
165 | unsigned int sel = MPP_SEL(*mpp_list); | ||
166 | int shift, gpio_mode; | ||
167 | |||
168 | if (num > MPP_MAX) { | ||
169 | pr_err("dove: invalid MPP number (%u)\n", num); | ||
170 | continue; | ||
171 | } | ||
172 | |||
173 | if (*mpp_list & MPP_NFC_MASK) { | ||
174 | dove_mpp_cfg_nfc(sel); | ||
175 | continue; | ||
176 | } | ||
177 | |||
178 | if (*mpp_list & MPP_AU1_MASK) { | ||
179 | dove_mpp_cfg_au1(sel); | ||
180 | continue; | ||
181 | } | ||
182 | |||
183 | if (*mpp_list & MPP_GRP_MASK) { | ||
184 | dove_mpp_conf_grp(num, sel, &mpp_ctrl[3]); | ||
185 | continue; | ||
186 | } | ||
187 | |||
188 | shift = (num & 7) << 2; | ||
189 | if (*mpp_list & MPP_PMU_MASK) { | ||
190 | pmu_mpp_ctrl |= (0x1 << num); | ||
191 | pmu_sig_ctrl[num / 8] &= ~(0xf << shift); | ||
192 | pmu_sig_ctrl[num / 8] |= 0xf << shift; | ||
193 | gpio_mode = 0; | ||
194 | } else { | ||
195 | mpp_ctrl[num / 8] &= ~(0xf << shift); | ||
196 | mpp_ctrl[num / 8] |= sel << shift; | ||
197 | gpio_mode = GPIO_OUTPUT_OK | GPIO_INPUT_OK; | ||
198 | } | ||
199 | |||
200 | orion_gpio_set_valid(num, gpio_mode); | ||
201 | } | ||
202 | |||
203 | for (i = 0; i < MPP_NR_REGS; i++) | ||
204 | writel(mpp_ctrl[i], MPP_CTRL(i)); | ||
205 | |||
206 | for (i = 0; i < PMU_SIG_REGS; i++) | ||
207 | writel(pmu_sig_ctrl[i], PMU_SIG_CTRL(i)); | ||
208 | |||
209 | writel(pmu_mpp_ctrl, DOVE_PMU_MPP_GENERAL_CTRL); | ||
210 | |||
211 | dove_mpp_dump_regs(); | ||
212 | } | ||
diff --git a/arch/arm/mach-dove/mpp.h b/arch/arm/mach-dove/mpp.h new file mode 100644 index 000000000000..2a43ce413b15 --- /dev/null +++ b/arch/arm/mach-dove/mpp.h | |||
@@ -0,0 +1,220 @@ | |||
1 | #ifndef __ARCH_DOVE_MPP_CODED_H | ||
2 | #define __ARCH_DOVE_MPP_CODED_H | ||
3 | |||
4 | #define MPP(_num, _mode, _pmu, _grp, _au1, _nfc) ( \ | ||
5 | /* MPP/group number */ ((_num) & 0xff) | \ | ||
6 | /* MPP select value */ (((_mode) & 0xf) << 8) | \ | ||
7 | /* MPP PMU */ ((!!(_pmu)) << 12) | \ | ||
8 | /* group flag */ ((!!(_grp)) << 13) | \ | ||
9 | /* AU1 flag */ ((!!(_au1)) << 14) | \ | ||
10 | /* NFCE flag */ ((!!(_nfc)) << 15)) | ||
11 | |||
12 | #define MPP_MAX 71 | ||
13 | |||
14 | #define MPP_NUM(x) ((x) & 0xff) | ||
15 | #define MPP_SEL(x) (((x) >> 8) & 0xf) | ||
16 | |||
17 | #define MPP_PMU_MASK MPP(0, 0x0, 1, 0, 0, 0) | ||
18 | #define MPP_GRP_MASK MPP(0, 0x0, 0, 1, 0, 0) | ||
19 | #define MPP_AU1_MASK MPP(0, 0x0, 0, 0, 1, 0) | ||
20 | #define MPP_NFC_MASK MPP(0, 0x0, 0, 0, 0, 1) | ||
21 | |||
22 | #define MPP_END MPP(0xff, 0xf, 1, 1, 1, 1) | ||
23 | |||
24 | #define MPP_PMU_DRIVE_0 0x1 | ||
25 | #define MPP_PMU_DRIVE_1 0x2 | ||
26 | #define MPP_PMU_SDI 0x3 | ||
27 | #define MPP_PMU_CPU_PWRDWN 0x4 | ||
28 | #define MPP_PMU_STBY_PWRDWN 0x5 | ||
29 | #define MPP_PMU_CORE_PWR_GOOD 0x8 | ||
30 | #define MPP_PMU_BAT_FAULT 0xa | ||
31 | #define MPP_PMU_EXT0_WU 0xb | ||
32 | #define MPP_PMU_EXT1_WU 0xc | ||
33 | #define MPP_PMU_EXT2_WU 0xd | ||
34 | #define MPP_PMU_BLINK 0xe | ||
35 | #define MPP_PMU(_num, _mode) MPP((_num), MPP_PMU_##_mode, 1, 0, 0, 0) | ||
36 | |||
37 | #define MPP_PIN(_num, _mode) MPP((_num), (_mode), 0, 0, 0, 0) | ||
38 | #define MPP_GRP(_grp, _mode) MPP((_grp), (_mode), 0, 1, 0, 0) | ||
39 | #define MPP_GRP_AU1(_mode) MPP(0, (_mode), 0, 0, 1, 0) | ||
40 | #define MPP_GRP_NFC(_mode) MPP(0, (_mode), 0, 0, 0, 1) | ||
41 | |||
42 | #define MPP0_GPIO0 MPP_PIN(0, 0x0) | ||
43 | #define MPP0_UA2_RTSn MPP_PIN(0, 0x2) | ||
44 | #define MPP0_SDIO0_CD MPP_PIN(0, 0x3) | ||
45 | #define MPP0_LCD0_PWM MPP_PIN(0, 0xf) | ||
46 | |||
47 | #define MPP1_GPIO1 MPP_PIN(1, 0x0) | ||
48 | #define MPP1_UA2_CTSn MPP_PIN(1, 0x2) | ||
49 | #define MPP1_SDIO0_WP MPP_PIN(1, 0x3) | ||
50 | #define MPP1_LCD1_PWM MPP_PIN(1, 0xf) | ||
51 | |||
52 | #define MPP2_GPIO2 MPP_PIN(2, 0x0) | ||
53 | #define MPP2_SATA_PRESENT MPP_PIN(2, 0x1) | ||
54 | #define MPP2_UA2_TXD MPP_PIN(2, 0x2) | ||
55 | #define MPP2_SDIO0_BUS_POWER MPP_PIN(2, 0x3) | ||
56 | #define MPP2_UA_RTSn1 MPP_PIN(2, 0x4) | ||
57 | |||
58 | #define MPP3_GPIO3 MPP_PIN(3, 0x0) | ||
59 | #define MPP3_SATA_ACT MPP_PIN(3, 0x1) | ||
60 | #define MPP3_UA2_RXD MPP_PIN(3, 0x2) | ||
61 | #define MPP3_SDIO0_LED_CTRL MPP_PIN(3, 0x3) | ||
62 | #define MPP3_UA_CTSn1 MPP_PIN(3, 0x4) | ||
63 | #define MPP3_SPI_LCD_CS1 MPP_PIN(3, 0xf) | ||
64 | |||
65 | #define MPP4_GPIO4 MPP_PIN(4, 0x0) | ||
66 | #define MPP4_UA3_RTSn MPP_PIN(4, 0x2) | ||
67 | #define MPP4_SDIO1_CD MPP_PIN(4, 0x3) | ||
68 | #define MPP4_SPI_1_MISO MPP_PIN(4, 0x4) | ||
69 | |||
70 | #define MPP5_GPIO5 MPP_PIN(5, 0x0) | ||
71 | #define MPP5_UA3_CTSn MPP_PIN(5, 0x2) | ||
72 | #define MPP5_SDIO1_WP MPP_PIN(5, 0x3) | ||
73 | #define MPP5_SPI_1_CS MPP_PIN(5, 0x4) | ||
74 | |||
75 | #define MPP6_GPIO6 MPP_PIN(6, 0x0) | ||
76 | #define MPP6_UA3_TXD MPP_PIN(6, 0x2) | ||
77 | #define MPP6_SDIO1_BUS_POWER MPP_PIN(6, 0x3) | ||
78 | #define MPP6_SPI_1_MOSI MPP_PIN(6, 0x4) | ||
79 | |||
80 | #define MPP7_GPIO7 MPP_PIN(7, 0x0) | ||
81 | #define MPP7_UA3_RXD MPP_PIN(7, 0x2) | ||
82 | #define MPP7_SDIO1_LED_CTRL MPP_PIN(7, 0x3) | ||
83 | #define MPP7_SPI_1_SCK MPP_PIN(7, 0x4) | ||
84 | |||
85 | #define MPP8_GPIO8 MPP_PIN(8, 0x0) | ||
86 | #define MPP8_WD_RST_OUT MPP_PIN(8, 0x1) | ||
87 | |||
88 | #define MPP9_GPIO9 MPP_PIN(9, 0x0) | ||
89 | #define MPP9_PEX1_CLKREQn MPP_PIN(9, 0x5) | ||
90 | |||
91 | #define MPP10_GPIO10 MPP_PIN(10, 0x0) | ||
92 | #define MPP10_SSP_SCLK MPP_PIN(10, 0x5) | ||
93 | |||
94 | #define MPP11_GPIO11 MPP_PIN(11, 0x0) | ||
95 | #define MPP11_SATA_PRESENT MPP_PIN(11, 0x1) | ||
96 | #define MPP11_SATA_ACT MPP_PIN(11, 0x2) | ||
97 | #define MPP11_SDIO0_LED_CTRL MPP_PIN(11, 0x3) | ||
98 | #define MPP11_SDIO1_LED_CTRL MPP_PIN(11, 0x4) | ||
99 | #define MPP11_PEX0_CLKREQn MPP_PIN(11, 0x5) | ||
100 | |||
101 | #define MPP12_GPIO12 MPP_PIN(12, 0x0) | ||
102 | #define MPP12_SATA_ACT MPP_PIN(12, 0x1) | ||
103 | #define MPP12_UA2_RTSn MPP_PIN(12, 0x2) | ||
104 | #define MPP12_AD0_I2S_EXT_MCLK MPP_PIN(12, 0x3) | ||
105 | #define MPP12_SDIO1_CD MPP_PIN(12, 0x4) | ||
106 | |||
107 | #define MPP13_GPIO13 MPP_PIN(13, 0x0) | ||
108 | #define MPP13_UA2_CTSn MPP_PIN(13, 0x2) | ||
109 | #define MPP13_AD1_I2S_EXT_MCLK MPP_PIN(13, 0x3) | ||
110 | #define MPP13_SDIO1WP MPP_PIN(13, 0x4) | ||
111 | #define MPP13_SSP_EXTCLK MPP_PIN(13, 0x5) | ||
112 | |||
113 | #define MPP14_GPIO14 MPP_PIN(14, 0x0) | ||
114 | #define MPP14_UA2_TXD MPP_PIN(14, 0x2) | ||
115 | #define MPP14_SDIO1_BUS_POWER MPP_PIN(14, 0x4) | ||
116 | #define MPP14_SSP_RXD MPP_PIN(14, 0x5) | ||
117 | |||
118 | #define MPP15_GPIO15 MPP_PIN(15, 0x0) | ||
119 | #define MPP15_UA2_RXD MPP_PIN(15, 0x2) | ||
120 | #define MPP15_SDIO1_LED_CTRL MPP_PIN(15, 0x4) | ||
121 | #define MPP15_SSP_SFRM MPP_PIN(15, 0x5) | ||
122 | |||
123 | #define MPP16_GPIO16 MPP_PIN(16, 0x0) | ||
124 | #define MPP16_UA3_RTSn MPP_PIN(16, 0x2) | ||
125 | #define MPP16_SDIO0_CD MPP_PIN(16, 0x3) | ||
126 | #define MPP16_SPI_LCD_CS1 MPP_PIN(16, 0x4) | ||
127 | #define MPP16_AC97_SDATA_IN1 MPP_PIN(16, 0x5) | ||
128 | |||
129 | #define MPP17_GPIO17 MPP_PIN(17, 0x0) | ||
130 | #define MPP17_AC97_SYSCLK_OUT MPP_PIN(17, 0x1) | ||
131 | #define MPP17_UA3_CTSn MPP_PIN(17, 0x2) | ||
132 | #define MPP17_SDIO0_WP MPP_PIN(17, 0x3) | ||
133 | #define MPP17_TW_SDA2 MPP_PIN(17, 0x4) | ||
134 | #define MPP17_AC97_SDATA_IN2 MPP_PIN(17, 0x5) | ||
135 | |||
136 | #define MPP18_GPIO18 MPP_PIN(18, 0x0) | ||
137 | #define MPP18_UA3_TXD MPP_PIN(18, 0x2) | ||
138 | #define MPP18_SDIO0_BUS_POWER MPP_PIN(18, 0x3) | ||
139 | #define MPP18_LCD0_PWM MPP_PIN(18, 0x4) | ||
140 | #define MPP18_AC_SDATA_IN3 MPP_PIN(18, 0x5) | ||
141 | |||
142 | #define MPP19_GPIO19 MPP_PIN(19, 0x0) | ||
143 | #define MPP19_UA3_RXD MPP_PIN(19, 0x2) | ||
144 | #define MPP19_SDIO0_LED_CTRL MPP_PIN(19, 0x3) | ||
145 | #define MPP19_TW_SCK2 MPP_PIN(19, 0x4) | ||
146 | |||
147 | #define MPP20_GPIO20 MPP_PIN(20, 0x0) | ||
148 | #define MPP20_AC97_SYSCLK_OUT MPP_PIN(20, 0x1) | ||
149 | #define MPP20_SPI_LCD_MISO MPP_PIN(20, 0x2) | ||
150 | #define MPP20_SDIO1_CD MPP_PIN(20, 0x3) | ||
151 | #define MPP20_SDIO0_CD MPP_PIN(20, 0x5) | ||
152 | #define MPP20_SPI_1_MISO MPP_PIN(20, 0x6) | ||
153 | |||
154 | #define MPP21_GPIO21 MPP_PIN(21, 0x0) | ||
155 | #define MPP21_UA1_RTSn MPP_PIN(21, 0x1) | ||
156 | #define MPP21_SPI_LCD_CS0 MPP_PIN(21, 0x2) | ||
157 | #define MPP21_SDIO1_WP MPP_PIN(21, 0x3) | ||
158 | #define MPP21_SSP_SFRM MPP_PIN(21, 0x4) | ||
159 | #define MPP21_SDIO0_WP MPP_PIN(21, 0x5) | ||
160 | #define MPP21_SPI_1_CS MPP_PIN(21, 0x6) | ||
161 | |||
162 | #define MPP22_GPIO22 MPP_PIN(22, 0x0) | ||
163 | #define MPP22_UA1_CTSn MPP_PIN(22, 0x1) | ||
164 | #define MPP22_SPI_LCD_MOSI MPP_PIN(22, 0x2) | ||
165 | #define MPP22_SDIO1_BUS_POWER MPP_PIN(22, 0x3) | ||
166 | #define MPP22_SSP_TXD MPP_PIN(22, 0x4) | ||
167 | #define MPP22_SDIO0_BUS_POWER MPP_PIN(22, 0x5) | ||
168 | #define MPP22_SPI_1_MOSI MPP_PIN(22, 0x6) | ||
169 | |||
170 | #define MPP23_GPIO23 MPP_PIN(23, 0x0) | ||
171 | #define MPP23_SPI_LCD_SCK MPP_PIN(23, 0x2) | ||
172 | #define MPP23_SDIO1_LED_CTRL MPP_PIN(23, 0x3) | ||
173 | #define MPP23_SSP_SCLK MPP_PIN(23, 0x4) | ||
174 | #define MPP23_SDIO0_LED_CTRL MPP_PIN(23, 0x5) | ||
175 | #define MPP23_SPI_1_SCK MPP_PIN(23, 0x6) | ||
176 | |||
177 | /* for MPP groups _num is a group index */ | ||
178 | enum dove_mpp_grp_idx { | ||
179 | MPP_24_39 = 2, | ||
180 | MPP_40_45 = 0, | ||
181 | MPP_46_51 = 1, | ||
182 | MPP_58_61 = 5, | ||
183 | MPP_62_63 = 4, | ||
184 | }; | ||
185 | |||
186 | #define MPP24_39_GPIO MPP_GRP(MPP_24_39, 0x1) | ||
187 | #define MPP24_39_CAM MPP_GRP(MPP_24_39, 0x0) | ||
188 | |||
189 | #define MPP40_45_GPIO MPP_GRP(MPP_40_45, 0x1) | ||
190 | #define MPP40_45_SD0 MPP_GRP(MPP_40_45, 0x0) | ||
191 | |||
192 | #define MPP46_51_GPIO MPP_GRP(MPP_46_51, 0x1) | ||
193 | #define MPP46_51_SD1 MPP_GRP(MPP_46_51, 0x0) | ||
194 | |||
195 | #define MPP58_61_GPIO MPP_GRP(MPP_58_61, 0x1) | ||
196 | #define MPP58_61_SPI MPP_GRP(MPP_58_61, 0x0) | ||
197 | |||
198 | #define MPP62_63_GPIO MPP_GRP(MPP_62_63, 0x1) | ||
199 | #define MPP62_63_UA1 MPP_GRP(MPP_62_63, 0x0) | ||
200 | |||
201 | /* The MPP[64:71] control differs from other groups */ | ||
202 | #define MPP64_71_GPO MPP_GRP_NFC(0x1) | ||
203 | #define MPP64_71_NFC MPP_GRP_NFC(0x0) | ||
204 | |||
205 | /* | ||
206 | * The MPP[52:57] functionality is encoded by 4 bits in different | ||
207 | * registers. The _num field in this case encodes those bits in | ||
208 | * correspodence with Table 135 of 88AP510 Functional specification | ||
209 | */ | ||
210 | #define MPP52_57_AU1 MPP_GRP_AU1(0x0) | ||
211 | #define MPP52_57_AU1_GPIO57 MPP_GRP_AU1(0x2) | ||
212 | #define MPP52_57_GPIO MPP_GRP_AU1(0xa) | ||
213 | #define MPP52_57_TW_GPIO MPP_GRP_AU1(0xb) | ||
214 | #define MPP52_57_AU1_SSP MPP_GRP_AU1(0xc) | ||
215 | #define MPP52_57_SSP_GPIO MPP_GRP_AU1(0xe) | ||
216 | #define MPP52_57_SSP_TW MPP_GRP_AU1(0xf) | ||
217 | |||
218 | void dove_mpp_conf(unsigned int *mpp_list); | ||
219 | |||
220 | #endif /* __ARCH_DOVE_MPP_CODED_H */ | ||
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 34106335c728..7fc603b46891 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig | |||
@@ -45,18 +45,18 @@ config MACH_GURUPLUG | |||
45 | Marvell GuruPlug Reference Board. | 45 | Marvell GuruPlug Reference Board. |
46 | 46 | ||
47 | config MACH_TS219 | 47 | config MACH_TS219 |
48 | bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS" | 48 | bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" |
49 | help | 49 | help |
50 | Say 'Y' here if you want your kernel to support the | 50 | Say 'Y' here if you want your kernel to support the |
51 | QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS | 51 | QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and |
52 | devices. | 52 | TS-219P+ Turbo NAS devices. |
53 | 53 | ||
54 | config MACH_TS41X | 54 | config MACH_TS41X |
55 | bool "QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS" | 55 | bool "QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo NAS" |
56 | help | 56 | help |
57 | Say 'Y' here if you want your kernel to support the | 57 | Say 'Y' here if you want your kernel to support the |
58 | QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS | 58 | QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo |
59 | devices. | 59 | NAS devices. |
60 | 60 | ||
61 | config MACH_DOCKSTAR | 61 | config MACH_DOCKSTAR |
62 | bool "Seagate FreeAgent DockStar" | 62 | bool "Seagate FreeAgent DockStar" |
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c index 6710bd7773b8..dc999c4c5806 100644 --- a/arch/arm/mach-kirkwood/ts219-setup.c +++ b/arch/arm/mach-kirkwood/ts219-setup.c | |||
@@ -80,15 +80,19 @@ static unsigned int qnap_ts219_mpp_config[] __initdata = { | |||
80 | MPP11_UART0_RXD, | 80 | MPP11_UART0_RXD, |
81 | MPP13_UART1_TXD, /* PIC controller */ | 81 | MPP13_UART1_TXD, /* PIC controller */ |
82 | MPP14_UART1_RXD, /* PIC controller */ | 82 | MPP14_UART1_RXD, /* PIC controller */ |
83 | MPP15_GPIO, /* USB Copy button */ | 83 | MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */ |
84 | MPP16_GPIO, /* Reset button */ | 84 | MPP16_GPIO, /* Reset button (on devices with 88F6281) */ |
85 | MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ | 85 | MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ |
86 | MPP37_GPIO, /* Reset button (on devices with 88F6282) */ | ||
87 | MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */ | ||
86 | MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */ | 88 | MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */ |
87 | 0 | 89 | 0 |
88 | }; | 90 | }; |
89 | 91 | ||
90 | static void __init qnap_ts219_init(void) | 92 | static void __init qnap_ts219_init(void) |
91 | { | 93 | { |
94 | u32 dev, rev; | ||
95 | |||
92 | /* | 96 | /* |
93 | * Basic setup. Needs to be called early. | 97 | * Basic setup. Needs to be called early. |
94 | */ | 98 | */ |
@@ -100,6 +104,14 @@ static void __init qnap_ts219_init(void) | |||
100 | qnap_tsx1x_register_flash(); | 104 | qnap_tsx1x_register_flash(); |
101 | kirkwood_i2c_init(); | 105 | kirkwood_i2c_init(); |
102 | i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1); | 106 | i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1); |
107 | |||
108 | kirkwood_pcie_id(&dev, &rev); | ||
109 | if (dev == MV88F6282_DEV_ID) { | ||
110 | qnap_ts219_buttons[0].gpio = 43; /* USB Copy button */ | ||
111 | qnap_ts219_buttons[1].gpio = 37; /* Reset button */ | ||
112 | qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); | ||
113 | } | ||
114 | |||
103 | kirkwood_ge00_init(&qnap_ts219_ge00_data); | 115 | kirkwood_ge00_init(&qnap_ts219_ge00_data); |
104 | kirkwood_sata_init(&qnap_ts219_sata_data); | 116 | kirkwood_sata_init(&qnap_ts219_sata_data); |
105 | kirkwood_ehci_init(); | 117 | kirkwood_ehci_init(); |
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c index 3587a281d993..9a44029915e2 100644 --- a/arch/arm/mach-kirkwood/ts41x-setup.c +++ b/arch/arm/mach-kirkwood/ts41x-setup.c | |||
@@ -119,6 +119,8 @@ static unsigned int qnap_ts41x_mpp_config[] __initdata = { | |||
119 | 119 | ||
120 | static void __init qnap_ts41x_init(void) | 120 | static void __init qnap_ts41x_init(void) |
121 | { | 121 | { |
122 | u32 dev, rev; | ||
123 | |||
122 | /* | 124 | /* |
123 | * Basic setup. Needs to be called early. | 125 | * Basic setup. Needs to be called early. |
124 | */ | 126 | */ |
@@ -130,8 +132,15 @@ static void __init qnap_ts41x_init(void) | |||
130 | qnap_tsx1x_register_flash(); | 132 | qnap_tsx1x_register_flash(); |
131 | kirkwood_i2c_init(); | 133 | kirkwood_i2c_init(); |
132 | i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1); | 134 | i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1); |
135 | |||
136 | kirkwood_pcie_id(&dev, &rev); | ||
137 | if (dev == MV88F6282_DEV_ID) { | ||
138 | qnap_ts41x_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); | ||
139 | qnap_ts41x_ge01_data.phy_addr = MV643XX_ETH_PHY_ADDR(1); | ||
140 | } | ||
133 | kirkwood_ge00_init(&qnap_ts41x_ge00_data); | 141 | kirkwood_ge00_init(&qnap_ts41x_ge00_data); |
134 | kirkwood_ge01_init(&qnap_ts41x_ge01_data); | 142 | kirkwood_ge01_init(&qnap_ts41x_ge01_data); |
143 | |||
135 | kirkwood_sata_init(&qnap_ts41x_sata_data); | 144 | kirkwood_sata_init(&qnap_ts41x_sata_data); |
136 | kirkwood_ehci_init(); | 145 | kirkwood_ehci_init(); |
137 | platform_device_register(&qnap_ts41x_button_device); | 146 | platform_device_register(&qnap_ts41x_button_device); |
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 0711d3b620ad..67793a690272 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig | |||
@@ -37,25 +37,38 @@ config MACH_TTC_DKB | |||
37 | Say 'Y' here if you want to support the Marvell PXA910-based | 37 | Say 'Y' here if you want to support the Marvell PXA910-based |
38 | TTC_DKB Development Board. | 38 | TTC_DKB Development Board. |
39 | 39 | ||
40 | config MACH_BROWNSTONE | ||
41 | bool "Marvell's Brownstone Development Platform" | ||
42 | depends on !CPU_MOHAWK | ||
43 | select CPU_MMP2 | ||
44 | help | ||
45 | Say 'Y' here if you want to support the Marvell MMP2-based | ||
46 | Brown Development Platform. | ||
47 | MMP2-based board can't be co-existed with PXA168-based & | ||
48 | PXA910-based development board. Since MMP2 is compatible to | ||
49 | ARMv7 architecture. | ||
50 | |||
40 | config MACH_FLINT | 51 | config MACH_FLINT |
41 | bool "Marvell's Flint Development Platform" | 52 | bool "Marvell's Flint Development Platform" |
53 | depends on !CPU_MOHAWK | ||
42 | select CPU_MMP2 | 54 | select CPU_MMP2 |
43 | help | 55 | help |
44 | Say 'Y' here if you want to support the Marvell MMP2-based | 56 | Say 'Y' here if you want to support the Marvell MMP2-based |
45 | Flint Development Platform. | 57 | Flint Development Platform. |
46 | MMP2-based board can't be co-existed with PXA168-based & | 58 | MMP2-based board can't be co-existed with PXA168-based & |
47 | PXA910-based development board. Since MMP2 is compatible to | 59 | PXA910-based development board. Since MMP2 is compatible to |
48 | ARMv6 architecture. | 60 | ARMv7 architecture. |
49 | 61 | ||
50 | config MACH_MARVELL_JASPER | 62 | config MACH_MARVELL_JASPER |
51 | bool "Marvell's Jasper Development Platform" | 63 | bool "Marvell's Jasper Development Platform" |
64 | depends on !CPU_MOHAWK | ||
52 | select CPU_MMP2 | 65 | select CPU_MMP2 |
53 | help | 66 | help |
54 | Say 'Y' here if you want to support the Marvell MMP2-base | 67 | Say 'Y' here if you want to support the Marvell MMP2-base |
55 | Jasper Development Platform. | 68 | Jasper Development Platform. |
56 | MMP2-based board can't be co-existed with PXA168-based & | 69 | MMP2-based board can't be co-existed with PXA168-based & |
57 | PXA910-based development board. Since MMP2 is compatible to | 70 | PXA910-based development board. Since MMP2 is compatible to |
58 | ARMv6 architecture. | 71 | ARMv7 architecture. |
59 | 72 | ||
60 | config MACH_TETON_BGA | 73 | config MACH_TETON_BGA |
61 | bool "Marvell's PXA168 Teton BGA Development Board" | 74 | bool "Marvell's PXA168 Teton BGA Development Board" |
@@ -80,8 +93,7 @@ config CPU_PXA910 | |||
80 | 93 | ||
81 | config CPU_MMP2 | 94 | config CPU_MMP2 |
82 | bool | 95 | bool |
83 | select CPU_V6 | 96 | select CPU_PJ4 |
84 | select CPU_32v6K | ||
85 | help | 97 | help |
86 | Select code specific to MMP2. MMP2 is ARMv6 compatible. | 98 | Select code specific to MMP2. MMP2 is ARMv7 compatible. |
87 | endif | 99 | endif |
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 751cdbf733c8..5c68382141af 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o | |||
15 | obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o | 15 | obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o |
16 | obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o | 16 | obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o |
17 | obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o | 17 | obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o |
18 | obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o | ||
18 | obj-$(CONFIG_MACH_FLINT) += flint.o | 19 | obj-$(CONFIG_MACH_FLINT) += flint.o |
19 | obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o | 20 | obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o |
20 | obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o | 21 | obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o |
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c new file mode 100644 index 000000000000..7bb78fd5a2a6 --- /dev/null +++ b/arch/arm/mach-mmp/brownstone.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/brownstone.c | ||
3 | * | ||
4 | * Support for the Marvell Brownstone Development Platform. | ||
5 | * | ||
6 | * Copyright (C) 2009-2010 Marvell International Ltd. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * publishhed by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/regulator/machine.h> | ||
19 | #include <linux/regulator/max8649.h> | ||
20 | #include <linux/regulator/fixed.h> | ||
21 | #include <linux/mfd/max8925.h> | ||
22 | |||
23 | #include <asm/mach-types.h> | ||
24 | #include <asm/mach/arch.h> | ||
25 | #include <mach/addr-map.h> | ||
26 | #include <mach/mfp-mmp2.h> | ||
27 | #include <mach/mmp2.h> | ||
28 | #include <mach/irqs.h> | ||
29 | |||
30 | #include "common.h" | ||
31 | |||
32 | #define BROWNSTONE_NR_IRQS (IRQ_BOARD_START + 40) | ||
33 | |||
34 | #define GPIO_5V_ENABLE (89) | ||
35 | |||
36 | static unsigned long brownstone_pin_config[] __initdata = { | ||
37 | /* UART1 */ | ||
38 | GPIO29_UART1_RXD, | ||
39 | GPIO30_UART1_TXD, | ||
40 | |||
41 | /* UART3 */ | ||
42 | GPIO51_UART3_RXD, | ||
43 | GPIO52_UART3_TXD, | ||
44 | |||
45 | /* DFI */ | ||
46 | GPIO168_DFI_D0, | ||
47 | GPIO167_DFI_D1, | ||
48 | GPIO166_DFI_D2, | ||
49 | GPIO165_DFI_D3, | ||
50 | GPIO107_DFI_D4, | ||
51 | GPIO106_DFI_D5, | ||
52 | GPIO105_DFI_D6, | ||
53 | GPIO104_DFI_D7, | ||
54 | GPIO111_DFI_D8, | ||
55 | GPIO164_DFI_D9, | ||
56 | GPIO163_DFI_D10, | ||
57 | GPIO162_DFI_D11, | ||
58 | GPIO161_DFI_D12, | ||
59 | GPIO110_DFI_D13, | ||
60 | GPIO109_DFI_D14, | ||
61 | GPIO108_DFI_D15, | ||
62 | GPIO143_ND_nCS0, | ||
63 | GPIO144_ND_nCS1, | ||
64 | GPIO147_ND_nWE, | ||
65 | GPIO148_ND_nRE, | ||
66 | GPIO150_ND_ALE, | ||
67 | GPIO149_ND_CLE, | ||
68 | GPIO112_ND_RDY0, | ||
69 | GPIO160_ND_RDY1, | ||
70 | |||
71 | /* PMIC */ | ||
72 | PMIC_PMIC_INT | MFP_LPM_EDGE_FALL, | ||
73 | |||
74 | /* MMC0 */ | ||
75 | GPIO131_MMC1_DAT3 | MFP_PULL_HIGH, | ||
76 | GPIO132_MMC1_DAT2 | MFP_PULL_HIGH, | ||
77 | GPIO133_MMC1_DAT1 | MFP_PULL_HIGH, | ||
78 | GPIO134_MMC1_DAT0 | MFP_PULL_HIGH, | ||
79 | GPIO136_MMC1_CMD | MFP_PULL_HIGH, | ||
80 | GPIO139_MMC1_CLK, | ||
81 | GPIO140_MMC1_CD | MFP_PULL_LOW, | ||
82 | GPIO141_MMC1_WP | MFP_PULL_LOW, | ||
83 | |||
84 | /* MMC1 */ | ||
85 | GPIO37_MMC2_DAT3 | MFP_PULL_HIGH, | ||
86 | GPIO38_MMC2_DAT2 | MFP_PULL_HIGH, | ||
87 | GPIO39_MMC2_DAT1 | MFP_PULL_HIGH, | ||
88 | GPIO40_MMC2_DAT0 | MFP_PULL_HIGH, | ||
89 | GPIO41_MMC2_CMD | MFP_PULL_HIGH, | ||
90 | GPIO42_MMC2_CLK, | ||
91 | |||
92 | /* MMC2 */ | ||
93 | GPIO165_MMC3_DAT7 | MFP_PULL_HIGH, | ||
94 | GPIO162_MMC3_DAT6 | MFP_PULL_HIGH, | ||
95 | GPIO166_MMC3_DAT5 | MFP_PULL_HIGH, | ||
96 | GPIO163_MMC3_DAT4 | MFP_PULL_HIGH, | ||
97 | GPIO167_MMC3_DAT3 | MFP_PULL_HIGH, | ||
98 | GPIO164_MMC3_DAT2 | MFP_PULL_HIGH, | ||
99 | GPIO168_MMC3_DAT1 | MFP_PULL_HIGH, | ||
100 | GPIO111_MMC3_DAT0 | MFP_PULL_HIGH, | ||
101 | GPIO112_MMC3_CMD | MFP_PULL_HIGH, | ||
102 | GPIO151_MMC3_CLK, | ||
103 | |||
104 | /* 5V regulator */ | ||
105 | GPIO89_GPIO, | ||
106 | }; | ||
107 | |||
108 | static struct regulator_consumer_supply max8649_supply[] = { | ||
109 | REGULATOR_SUPPLY("vcc_core", NULL), | ||
110 | }; | ||
111 | |||
112 | static struct regulator_init_data max8649_init_data = { | ||
113 | .constraints = { | ||
114 | .name = "vcc_core range", | ||
115 | .min_uV = 1150000, | ||
116 | .max_uV = 1280000, | ||
117 | .always_on = 1, | ||
118 | .boot_on = 1, | ||
119 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, | ||
120 | }, | ||
121 | .num_consumer_supplies = 1, | ||
122 | .consumer_supplies = &max8649_supply[0], | ||
123 | }; | ||
124 | |||
125 | static struct max8649_platform_data brownstone_max8649_info = { | ||
126 | .mode = 2, /* VID1 = 1, VID0 = 0 */ | ||
127 | .extclk = 0, | ||
128 | .ramp_timing = MAX8649_RAMP_32MV, | ||
129 | .regulator = &max8649_init_data, | ||
130 | }; | ||
131 | |||
132 | static struct regulator_consumer_supply brownstone_v_5vp_supplies[] = { | ||
133 | REGULATOR_SUPPLY("v_5vp", NULL), | ||
134 | }; | ||
135 | |||
136 | static struct regulator_init_data brownstone_v_5vp_data = { | ||
137 | .constraints = { | ||
138 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
139 | }, | ||
140 | .num_consumer_supplies = ARRAY_SIZE(brownstone_v_5vp_supplies), | ||
141 | .consumer_supplies = brownstone_v_5vp_supplies, | ||
142 | }; | ||
143 | |||
144 | static struct fixed_voltage_config brownstone_v_5vp = { | ||
145 | .supply_name = "v_5vp", | ||
146 | .microvolts = 5000000, | ||
147 | .gpio = GPIO_5V_ENABLE, | ||
148 | .enable_high = 1, | ||
149 | .enabled_at_boot = 1, | ||
150 | .init_data = &brownstone_v_5vp_data, | ||
151 | }; | ||
152 | |||
153 | static struct platform_device brownstone_v_5vp_device = { | ||
154 | .name = "reg-fixed-voltage", | ||
155 | .id = 1, | ||
156 | .dev = { | ||
157 | .platform_data = &brownstone_v_5vp, | ||
158 | }, | ||
159 | }; | ||
160 | |||
161 | static struct max8925_platform_data brownstone_max8925_info = { | ||
162 | .irq_base = IRQ_BOARD_START, | ||
163 | }; | ||
164 | |||
165 | static struct i2c_board_info brownstone_twsi1_info[] = { | ||
166 | [0] = { | ||
167 | .type = "max8649", | ||
168 | .addr = 0x60, | ||
169 | .platform_data = &brownstone_max8649_info, | ||
170 | }, | ||
171 | [1] = { | ||
172 | .type = "max8925", | ||
173 | .addr = 0x3c, | ||
174 | .irq = IRQ_MMP2_PMIC, | ||
175 | .platform_data = &brownstone_max8925_info, | ||
176 | }, | ||
177 | }; | ||
178 | |||
179 | static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { | ||
180 | .max_speed = 25000000, | ||
181 | }; | ||
182 | |||
183 | static void __init brownstone_init(void) | ||
184 | { | ||
185 | mfp_config(ARRAY_AND_SIZE(brownstone_pin_config)); | ||
186 | |||
187 | /* on-chip devices */ | ||
188 | mmp2_add_uart(1); | ||
189 | mmp2_add_uart(3); | ||
190 | mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); | ||
191 | mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ | ||
192 | |||
193 | /* enable 5v regulator */ | ||
194 | platform_device_register(&brownstone_v_5vp_device); | ||
195 | } | ||
196 | |||
197 | MACHINE_START(BROWNSTONE, "Brownstone Development Platform") | ||
198 | /* Maintainer: Haojian Zhuang <haojian.zhuang@marvell.com> */ | ||
199 | .map_io = mmp_map_io, | ||
200 | .nr_irqs = BROWNSTONE_NR_IRQS, | ||
201 | .init_irq = mmp2_init_irq, | ||
202 | .timer = &mmp2_timer, | ||
203 | .init_machine = brownstone_init, | ||
204 | MACHINE_END | ||
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c index bdeb6db4d49a..c4fd806b15b4 100644 --- a/arch/arm/mach-mmp/flint.c +++ b/arch/arm/mach-mmp/flint.c | |||
@@ -47,7 +47,7 @@ static unsigned long flint_pin_config[] __initdata = { | |||
47 | GPIO113_SMC_RDY, | 47 | GPIO113_SMC_RDY, |
48 | 48 | ||
49 | /*Ethernet*/ | 49 | /*Ethernet*/ |
50 | GPIO155_GPIO155, | 50 | GPIO155_GPIO, |
51 | 51 | ||
52 | /* DFI */ | 52 | /* DFI */ |
53 | GPIO168_DFI_D0, | 53 | GPIO168_DFI_D0, |
diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h index 761c2dacc079..117e30366087 100644 --- a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h | |||
@@ -9,175 +9,175 @@ | |||
9 | #define MFP_DRIVE_FAST (0x8 << 13) | 9 | #define MFP_DRIVE_FAST (0x8 << 13) |
10 | 10 | ||
11 | /* GPIO */ | 11 | /* GPIO */ |
12 | #define GPIO0_GPIO0 MFP_CFG(GPIO0, AF0) | 12 | #define GPIO0_GPIO MFP_CFG(GPIO0, AF0) |
13 | #define GPIO1_GPIO1 MFP_CFG(GPIO1, AF0) | 13 | #define GPIO1_GPIO MFP_CFG(GPIO1, AF0) |
14 | #define GPIO2_GPIO2 MFP_CFG(GPIO2, AF0) | 14 | #define GPIO2_GPIO MFP_CFG(GPIO2, AF0) |
15 | #define GPIO3_GPIO3 MFP_CFG(GPIO3, AF0) | 15 | #define GPIO3_GPIO MFP_CFG(GPIO3, AF0) |
16 | #define GPIO4_GPIO4 MFP_CFG(GPIO4, AF0) | 16 | #define GPIO4_GPIO MFP_CFG(GPIO4, AF0) |
17 | #define GPIO5_GPIO5 MFP_CFG(GPIO5, AF0) | 17 | #define GPIO5_GPIO MFP_CFG(GPIO5, AF0) |
18 | #define GPIO6_GPIO6 MFP_CFG(GPIO6, AF0) | 18 | #define GPIO6_GPIO MFP_CFG(GPIO6, AF0) |
19 | #define GPIO7_GPIO7 MFP_CFG(GPIO7, AF0) | 19 | #define GPIO7_GPIO MFP_CFG(GPIO7, AF0) |
20 | #define GPIO8_GPIO8 MFP_CFG(GPIO8, AF0) | 20 | #define GPIO8_GPIO MFP_CFG(GPIO8, AF0) |
21 | #define GPIO9_GPIO9 MFP_CFG(GPIO9, AF0) | 21 | #define GPIO9_GPIO MFP_CFG(GPIO9, AF0) |
22 | #define GPIO10_GPIO10 MFP_CFG(GPIO10, AF0) | 22 | #define GPIO10_GPIO MFP_CFG(GPIO10, AF0) |
23 | #define GPIO11_GPIO11 MFP_CFG(GPIO11, AF0) | 23 | #define GPIO11_GPIO MFP_CFG(GPIO11, AF0) |
24 | #define GPIO12_GPIO12 MFP_CFG(GPIO12, AF0) | 24 | #define GPIO12_GPIO MFP_CFG(GPIO12, AF0) |
25 | #define GPIO13_GPIO13 MFP_CFG(GPIO13, AF0) | 25 | #define GPIO13_GPIO MFP_CFG(GPIO13, AF0) |
26 | #define GPIO14_GPIO14 MFP_CFG(GPIO14, AF0) | 26 | #define GPIO14_GPIO MFP_CFG(GPIO14, AF0) |
27 | #define GPIO15_GPIO15 MFP_CFG(GPIO15, AF0) | 27 | #define GPIO15_GPIO MFP_CFG(GPIO15, AF0) |
28 | #define GPIO16_GPIO16 MFP_CFG(GPIO16, AF0) | 28 | #define GPIO16_GPIO MFP_CFG(GPIO16, AF0) |
29 | #define GPIO17_GPIO17 MFP_CFG(GPIO17, AF0) | 29 | #define GPIO17_GPIO MFP_CFG(GPIO17, AF0) |
30 | #define GPIO18_GPIO18 MFP_CFG(GPIO18, AF0) | 30 | #define GPIO18_GPIO MFP_CFG(GPIO18, AF0) |
31 | #define GPIO19_GPIO19 MFP_CFG(GPIO19, AF0) | 31 | #define GPIO19_GPIO MFP_CFG(GPIO19, AF0) |
32 | #define GPIO20_GPIO20 MFP_CFG(GPIO20, AF0) | 32 | #define GPIO20_GPIO MFP_CFG(GPIO20, AF0) |
33 | #define GPIO21_GPIO21 MFP_CFG(GPIO21, AF0) | 33 | #define GPIO21_GPIO MFP_CFG(GPIO21, AF0) |
34 | #define GPIO22_GPIO22 MFP_CFG(GPIO22, AF0) | 34 | #define GPIO22_GPIO MFP_CFG(GPIO22, AF0) |
35 | #define GPIO23_GPIO23 MFP_CFG(GPIO23, AF0) | 35 | #define GPIO23_GPIO MFP_CFG(GPIO23, AF0) |
36 | #define GPIO24_GPIO24 MFP_CFG(GPIO24, AF0) | 36 | #define GPIO24_GPIO MFP_CFG(GPIO24, AF0) |
37 | #define GPIO25_GPIO25 MFP_CFG(GPIO25, AF0) | 37 | #define GPIO25_GPIO MFP_CFG(GPIO25, AF0) |
38 | #define GPIO26_GPIO26 MFP_CFG(GPIO26, AF0) | 38 | #define GPIO26_GPIO MFP_CFG(GPIO26, AF0) |
39 | #define GPIO27_GPIO27 MFP_CFG(GPIO27, AF0) | 39 | #define GPIO27_GPIO MFP_CFG(GPIO27, AF0) |
40 | #define GPIO28_GPIO28 MFP_CFG(GPIO28, AF0) | 40 | #define GPIO28_GPIO MFP_CFG(GPIO28, AF0) |
41 | #define GPIO29_GPIO29 MFP_CFG(GPIO29, AF0) | 41 | #define GPIO29_GPIO MFP_CFG(GPIO29, AF0) |
42 | #define GPIO30_GPIO30 MFP_CFG(GPIO30, AF0) | 42 | #define GPIO30_GPIO MFP_CFG(GPIO30, AF0) |
43 | #define GPIO31_GPIO31 MFP_CFG(GPIO31, AF0) | 43 | #define GPIO31_GPIO MFP_CFG(GPIO31, AF0) |
44 | #define GPIO32_GPIO32 MFP_CFG(GPIO32, AF0) | 44 | #define GPIO32_GPIO MFP_CFG(GPIO32, AF0) |
45 | #define GPIO33_GPIO33 MFP_CFG(GPIO33, AF0) | 45 | #define GPIO33_GPIO MFP_CFG(GPIO33, AF0) |
46 | #define GPIO34_GPIO34 MFP_CFG(GPIO34, AF0) | 46 | #define GPIO34_GPIO MFP_CFG(GPIO34, AF0) |
47 | #define GPIO35_GPIO35 MFP_CFG(GPIO35, AF0) | 47 | #define GPIO35_GPIO MFP_CFG(GPIO35, AF0) |
48 | #define GPIO36_GPIO36 MFP_CFG(GPIO36, AF0) | 48 | #define GPIO36_GPIO MFP_CFG(GPIO36, AF0) |
49 | #define GPIO37_GPIO37 MFP_CFG(GPIO37, AF0) | 49 | #define GPIO37_GPIO MFP_CFG(GPIO37, AF0) |
50 | #define GPIO38_GPIO38 MFP_CFG(GPIO38, AF0) | 50 | #define GPIO38_GPIO MFP_CFG(GPIO38, AF0) |
51 | #define GPIO39_GPIO39 MFP_CFG(GPIO39, AF0) | 51 | #define GPIO39_GPIO MFP_CFG(GPIO39, AF0) |
52 | #define GPIO40_GPIO40 MFP_CFG(GPIO40, AF0) | 52 | #define GPIO40_GPIO MFP_CFG(GPIO40, AF0) |
53 | #define GPIO41_GPIO41 MFP_CFG(GPIO41, AF0) | 53 | #define GPIO41_GPIO MFP_CFG(GPIO41, AF0) |
54 | #define GPIO42_GPIO42 MFP_CFG(GPIO42, AF0) | 54 | #define GPIO42_GPIO MFP_CFG(GPIO42, AF0) |
55 | #define GPIO43_GPIO43 MFP_CFG(GPIO43, AF0) | 55 | #define GPIO43_GPIO MFP_CFG(GPIO43, AF0) |
56 | #define GPIO44_GPIO44 MFP_CFG(GPIO44, AF0) | 56 | #define GPIO44_GPIO MFP_CFG(GPIO44, AF0) |
57 | #define GPIO45_GPIO45 MFP_CFG(GPIO45, AF0) | 57 | #define GPIO45_GPIO MFP_CFG(GPIO45, AF0) |
58 | #define GPIO46_GPIO46 MFP_CFG(GPIO46, AF0) | 58 | #define GPIO46_GPIO MFP_CFG(GPIO46, AF0) |
59 | #define GPIO47_GPIO47 MFP_CFG(GPIO47, AF0) | 59 | #define GPIO47_GPIO MFP_CFG(GPIO47, AF0) |
60 | #define GPIO48_GPIO48 MFP_CFG(GPIO48, AF0) | 60 | #define GPIO48_GPIO MFP_CFG(GPIO48, AF0) |
61 | #define GPIO49_GPIO49 MFP_CFG(GPIO49, AF0) | 61 | #define GPIO49_GPIO MFP_CFG(GPIO49, AF0) |
62 | #define GPIO50_GPIO50 MFP_CFG(GPIO50, AF0) | 62 | #define GPIO50_GPIO MFP_CFG(GPIO50, AF0) |
63 | #define GPIO51_GPIO51 MFP_CFG(GPIO51, AF0) | 63 | #define GPIO51_GPIO MFP_CFG(GPIO51, AF0) |
64 | #define GPIO52_GPIO52 MFP_CFG(GPIO52, AF0) | 64 | #define GPIO52_GPIO MFP_CFG(GPIO52, AF0) |
65 | #define GPIO53_GPIO53 MFP_CFG(GPIO53, AF0) | 65 | #define GPIO53_GPIO MFP_CFG(GPIO53, AF0) |
66 | #define GPIO54_GPIO54 MFP_CFG(GPIO54, AF0) | 66 | #define GPIO54_GPIO MFP_CFG(GPIO54, AF0) |
67 | #define GPIO55_GPIO55 MFP_CFG(GPIO55, AF0) | 67 | #define GPIO55_GPIO MFP_CFG(GPIO55, AF0) |
68 | #define GPIO56_GPIO56 MFP_CFG(GPIO56, AF0) | 68 | #define GPIO56_GPIO MFP_CFG(GPIO56, AF0) |
69 | #define GPIO57_GPIO57 MFP_CFG(GPIO57, AF0) | 69 | #define GPIO57_GPIO MFP_CFG(GPIO57, AF0) |
70 | #define GPIO58_GPIO58 MFP_CFG(GPIO58, AF0) | 70 | #define GPIO58_GPIO MFP_CFG(GPIO58, AF0) |
71 | #define GPIO59_GPIO59 MFP_CFG(GPIO59, AF0) | 71 | #define GPIO59_GPIO MFP_CFG(GPIO59, AF0) |
72 | #define GPIO60_GPIO60 MFP_CFG(GPIO60, AF0) | 72 | #define GPIO60_GPIO MFP_CFG(GPIO60, AF0) |
73 | #define GPIO61_GPIO61 MFP_CFG(GPIO61, AF0) | 73 | #define GPIO61_GPIO MFP_CFG(GPIO61, AF0) |
74 | #define GPIO62_GPIO62 MFP_CFG(GPIO62, AF0) | 74 | #define GPIO62_GPIO MFP_CFG(GPIO62, AF0) |
75 | #define GPIO63_GPIO63 MFP_CFG(GPIO63, AF0) | 75 | #define GPIO63_GPIO MFP_CFG(GPIO63, AF0) |
76 | #define GPIO64_GPIO64 MFP_CFG(GPIO64, AF0) | 76 | #define GPIO64_GPIO MFP_CFG(GPIO64, AF0) |
77 | #define GPIO65_GPIO65 MFP_CFG(GPIO65, AF0) | 77 | #define GPIO65_GPIO MFP_CFG(GPIO65, AF0) |
78 | #define GPIO66_GPIO66 MFP_CFG(GPIO66, AF0) | 78 | #define GPIO66_GPIO MFP_CFG(GPIO66, AF0) |
79 | #define GPIO67_GPIO67 MFP_CFG(GPIO67, AF0) | 79 | #define GPIO67_GPIO MFP_CFG(GPIO67, AF0) |
80 | #define GPIO68_GPIO68 MFP_CFG(GPIO68, AF0) | 80 | #define GPIO68_GPIO MFP_CFG(GPIO68, AF0) |
81 | #define GPIO69_GPIO69 MFP_CFG(GPIO69, AF0) | 81 | #define GPIO69_GPIO MFP_CFG(GPIO69, AF0) |
82 | #define GPIO70_GPIO70 MFP_CFG(GPIO70, AF0) | 82 | #define GPIO70_GPIO MFP_CFG(GPIO70, AF0) |
83 | #define GPIO71_GPIO71 MFP_CFG(GPIO71, AF0) | 83 | #define GPIO71_GPIO MFP_CFG(GPIO71, AF0) |
84 | #define GPIO72_GPIO72 MFP_CFG(GPIO72, AF0) | 84 | #define GPIO72_GPIO MFP_CFG(GPIO72, AF0) |
85 | #define GPIO73_GPIO73 MFP_CFG(GPIO73, AF0) | 85 | #define GPIO73_GPIO MFP_CFG(GPIO73, AF0) |
86 | #define GPIO74_GPIO74 MFP_CFG(GPIO74, AF0) | 86 | #define GPIO74_GPIO MFP_CFG(GPIO74, AF0) |
87 | #define GPIO75_GPIO75 MFP_CFG(GPIO75, AF0) | 87 | #define GPIO75_GPIO MFP_CFG(GPIO75, AF0) |
88 | #define GPIO76_GPIO76 MFP_CFG(GPIO76, AF0) | 88 | #define GPIO76_GPIO MFP_CFG(GPIO76, AF0) |
89 | #define GPIO77_GPIO77 MFP_CFG(GPIO77, AF0) | 89 | #define GPIO77_GPIO MFP_CFG(GPIO77, AF0) |
90 | #define GPIO78_GPIO78 MFP_CFG(GPIO78, AF0) | 90 | #define GPIO78_GPIO MFP_CFG(GPIO78, AF0) |
91 | #define GPIO79_GPIO79 MFP_CFG(GPIO79, AF0) | 91 | #define GPIO79_GPIO MFP_CFG(GPIO79, AF0) |
92 | #define GPIO80_GPIO80 MFP_CFG(GPIO80, AF0) | 92 | #define GPIO80_GPIO MFP_CFG(GPIO80, AF0) |
93 | #define GPIO81_GPIO81 MFP_CFG(GPIO81, AF0) | 93 | #define GPIO81_GPIO MFP_CFG(GPIO81, AF0) |
94 | #define GPIO82_GPIO82 MFP_CFG(GPIO82, AF0) | 94 | #define GPIO82_GPIO MFP_CFG(GPIO82, AF0) |
95 | #define GPIO83_GPIO83 MFP_CFG(GPIO83, AF0) | 95 | #define GPIO83_GPIO MFP_CFG(GPIO83, AF0) |
96 | #define GPIO84_GPIO84 MFP_CFG(GPIO84, AF0) | 96 | #define GPIO84_GPIO MFP_CFG(GPIO84, AF0) |
97 | #define GPIO85_GPIO85 MFP_CFG(GPIO85, AF0) | 97 | #define GPIO85_GPIO MFP_CFG(GPIO85, AF0) |
98 | #define GPIO86_GPIO86 MFP_CFG(GPIO86, AF0) | 98 | #define GPIO86_GPIO MFP_CFG(GPIO86, AF0) |
99 | #define GPIO87_GPIO87 MFP_CFG(GPIO87, AF0) | 99 | #define GPIO87_GPIO MFP_CFG(GPIO87, AF0) |
100 | #define GPIO88_GPIO88 MFP_CFG(GPIO88, AF0) | 100 | #define GPIO88_GPIO MFP_CFG(GPIO88, AF0) |
101 | #define GPIO89_GPIO89 MFP_CFG(GPIO89, AF0) | 101 | #define GPIO89_GPIO MFP_CFG(GPIO89, AF0) |
102 | #define GPIO90_GPIO90 MFP_CFG(GPIO90, AF0) | 102 | #define GPIO90_GPIO MFP_CFG(GPIO90, AF0) |
103 | #define GPIO91_GPIO91 MFP_CFG(GPIO91, AF0) | 103 | #define GPIO91_GPIO MFP_CFG(GPIO91, AF0) |
104 | #define GPIO92_GPIO92 MFP_CFG(GPIO92, AF0) | 104 | #define GPIO92_GPIO MFP_CFG(GPIO92, AF0) |
105 | #define GPIO93_GPIO93 MFP_CFG(GPIO93, AF0) | 105 | #define GPIO93_GPIO MFP_CFG(GPIO93, AF0) |
106 | #define GPIO94_GPIO94 MFP_CFG(GPIO94, AF0) | 106 | #define GPIO94_GPIO MFP_CFG(GPIO94, AF0) |
107 | #define GPIO95_GPIO95 MFP_CFG(GPIO95, AF0) | 107 | #define GPIO95_GPIO MFP_CFG(GPIO95, AF0) |
108 | #define GPIO96_GPIO96 MFP_CFG(GPIO96, AF0) | 108 | #define GPIO96_GPIO MFP_CFG(GPIO96, AF0) |
109 | #define GPIO97_GPIO97 MFP_CFG(GPIO97, AF0) | 109 | #define GPIO97_GPIO MFP_CFG(GPIO97, AF0) |
110 | #define GPIO98_GPIO98 MFP_CFG(GPIO98, AF0) | 110 | #define GPIO98_GPIO MFP_CFG(GPIO98, AF0) |
111 | #define GPIO99_GPIO99 MFP_CFG(GPIO99, AF0) | 111 | #define GPIO99_GPIO MFP_CFG(GPIO99, AF0) |
112 | #define GPIO100_GPIO100 MFP_CFG(GPIO100, AF0) | 112 | #define GPIO100_GPIO MFP_CFG(GPIO100, AF0) |
113 | #define GPIO101_GPIO101 MFP_CFG(GPIO101, AF0) | 113 | #define GPIO101_GPIO MFP_CFG(GPIO101, AF0) |
114 | #define GPIO102_GPIO102 MFP_CFG(GPIO102, AF1) | 114 | #define GPIO102_GPIO MFP_CFG(GPIO102, AF1) |
115 | #define GPIO103_GPIO103 MFP_CFG(GPIO103, AF1) | 115 | #define GPIO103_GPIO MFP_CFG(GPIO103, AF1) |
116 | #define GPIO104_GPIO104 MFP_CFG(GPIO104, AF1) | 116 | #define GPIO104_GPIO MFP_CFG(GPIO104, AF1) |
117 | #define GPIO105_GPIO105 MFP_CFG(GPIO105, AF1) | 117 | #define GPIO105_GPIO MFP_CFG(GPIO105, AF1) |
118 | #define GPIO106_GPIO106 MFP_CFG(GPIO106, AF1) | 118 | #define GPIO106_GPIO MFP_CFG(GPIO106, AF1) |
119 | #define GPIO107_GPIO107 MFP_CFG(GPIO107, AF1) | 119 | #define GPIO107_GPIO MFP_CFG(GPIO107, AF1) |
120 | #define GPIO108_GPIO108 MFP_CFG(GPIO108, AF1) | 120 | #define GPIO108_GPIO MFP_CFG(GPIO108, AF1) |
121 | #define GPIO109_GPIO109 MFP_CFG(GPIO109, AF1) | 121 | #define GPIO109_GPIO MFP_CFG(GPIO109, AF1) |
122 | #define GPIO110_GPIO110 MFP_CFG(GPIO110, AF1) | 122 | #define GPIO110_GPIO MFP_CFG(GPIO110, AF1) |
123 | #define GPIO111_GPIO111 MFP_CFG(GPIO111, AF1) | 123 | #define GPIO111_GPIO MFP_CFG(GPIO111, AF1) |
124 | #define GPIO112_GPIO112 MFP_CFG(GPIO112, AF1) | 124 | #define GPIO112_GPIO MFP_CFG(GPIO112, AF1) |
125 | #define GPIO113_GPIO113 MFP_CFG(GPIO113, AF1) | 125 | #define GPIO113_GPIO MFP_CFG(GPIO113, AF1) |
126 | #define GPIO114_GPIO114 MFP_CFG(GPIO114, AF0) | 126 | #define GPIO114_GPIO MFP_CFG(GPIO114, AF0) |
127 | #define GPIO115_GPIO115 MFP_CFG(GPIO115, AF0) | 127 | #define GPIO115_GPIO MFP_CFG(GPIO115, AF0) |
128 | #define GPIO116_GPIO116 MFP_CFG(GPIO116, AF0) | 128 | #define GPIO116_GPIO MFP_CFG(GPIO116, AF0) |
129 | #define GPIO117_GPIO117 MFP_CFG(GPIO117, AF0) | 129 | #define GPIO117_GPIO MFP_CFG(GPIO117, AF0) |
130 | #define GPIO118_GPIO118 MFP_CFG(GPIO118, AF0) | 130 | #define GPIO118_GPIO MFP_CFG(GPIO118, AF0) |
131 | #define GPIO119_GPIO119 MFP_CFG(GPIO119, AF0) | 131 | #define GPIO119_GPIO MFP_CFG(GPIO119, AF0) |
132 | #define GPIO120_GPIO120 MFP_CFG(GPIO120, AF0) | 132 | #define GPIO120_GPIO MFP_CFG(GPIO120, AF0) |
133 | #define GPIO121_GPIO121 MFP_CFG(GPIO121, AF0) | 133 | #define GPIO121_GPIO MFP_CFG(GPIO121, AF0) |
134 | #define GPIO122_GPIO122 MFP_CFG(GPIO122, AF0) | 134 | #define GPIO122_GPIO MFP_CFG(GPIO122, AF0) |
135 | #define GPIO123_GPIO123 MFP_CFG(GPIO123, AF0) | 135 | #define GPIO123_GPIO MFP_CFG(GPIO123, AF0) |
136 | #define GPIO124_GPIO124 MFP_CFG(GPIO124, AF0) | 136 | #define GPIO124_GPIO MFP_CFG(GPIO124, AF0) |
137 | #define GPIO125_GPIO125 MFP_CFG(GPIO125, AF0) | 137 | #define GPIO125_GPIO MFP_CFG(GPIO125, AF0) |
138 | #define GPIO126_GPIO126 MFP_CFG(GPIO126, AF0) | 138 | #define GPIO126_GPIO MFP_CFG(GPIO126, AF0) |
139 | #define GPIO127_GPIO127 MFP_CFG(GPIO127, AF0) | 139 | #define GPIO127_GPIO MFP_CFG(GPIO127, AF0) |
140 | #define GPIO128_GPIO128 MFP_CFG(GPIO128, AF0) | 140 | #define GPIO128_GPIO MFP_CFG(GPIO128, AF0) |
141 | #define GPIO129_GPIO129 MFP_CFG(GPIO129, AF0) | 141 | #define GPIO129_GPIO MFP_CFG(GPIO129, AF0) |
142 | #define GPIO130_GPIO130 MFP_CFG(GPIO130, AF0) | 142 | #define GPIO130_GPIO MFP_CFG(GPIO130, AF0) |
143 | #define GPIO131_GPIO131 MFP_CFG(GPIO131, AF0) | 143 | #define GPIO131_GPIO MFP_CFG(GPIO131, AF0) |
144 | #define GPIO132_GPIO132 MFP_CFG(GPIO132, AF0) | 144 | #define GPIO132_GPIO MFP_CFG(GPIO132, AF0) |
145 | #define GPIO133_GPIO133 MFP_CFG(GPIO133, AF0) | 145 | #define GPIO133_GPIO MFP_CFG(GPIO133, AF0) |
146 | #define GPIO134_GPIO134 MFP_CFG(GPIO134, AF0) | 146 | #define GPIO134_GPIO MFP_CFG(GPIO134, AF0) |
147 | #define GPIO135_GPIO135 MFP_CFG(GPIO135, AF0) | 147 | #define GPIO135_GPIO MFP_CFG(GPIO135, AF0) |
148 | #define GPIO136_GPIO136 MFP_CFG(GPIO136, AF0) | 148 | #define GPIO136_GPIO MFP_CFG(GPIO136, AF0) |
149 | #define GPIO137_GPIO137 MFP_CFG(GPIO137, AF0) | 149 | #define GPIO137_GPIO MFP_CFG(GPIO137, AF0) |
150 | #define GPIO138_GPIO138 MFP_CFG(GPIO138, AF0) | 150 | #define GPIO138_GPIO MFP_CFG(GPIO138, AF0) |
151 | #define GPIO139_GPIO139 MFP_CFG(GPIO139, AF0) | 151 | #define GPIO139_GPIO MFP_CFG(GPIO139, AF0) |
152 | #define GPIO140_GPIO140 MFP_CFG(GPIO140, AF0) | 152 | #define GPIO140_GPIO MFP_CFG(GPIO140, AF0) |
153 | #define GPIO141_GPIO141 MFP_CFG(GPIO141, AF0) | 153 | #define GPIO141_GPIO MFP_CFG(GPIO141, AF0) |
154 | #define GPIO142_GPIO142 MFP_CFG(GPIO142, AF1) | 154 | #define GPIO142_GPIO MFP_CFG(GPIO142, AF1) |
155 | #define GPIO143_GPIO143 MFP_CFG(GPIO143, AF1) | 155 | #define GPIO143_GPIO MFP_CFG(GPIO143, AF1) |
156 | #define GPIO144_GPIO144 MFP_CFG(GPIO144, AF1) | 156 | #define GPIO144_GPIO MFP_CFG(GPIO144, AF1) |
157 | #define GPIO145_GPIO145 MFP_CFG(GPIO145, AF1) | 157 | #define GPIO145_GPIO MFP_CFG(GPIO145, AF1) |
158 | #define GPIO146_GPIO146 MFP_CFG(GPIO146, AF1) | 158 | #define GPIO146_GPIO MFP_CFG(GPIO146, AF1) |
159 | #define GPIO147_GPIO147 MFP_CFG(GPIO147, AF1) | 159 | #define GPIO147_GPIO MFP_CFG(GPIO147, AF1) |
160 | #define GPIO148_GPIO148 MFP_CFG(GPIO148, AF1) | 160 | #define GPIO148_GPIO MFP_CFG(GPIO148, AF1) |
161 | #define GPIO149_GPIO149 MFP_CFG(GPIO149, AF1) | 161 | #define GPIO149_GPIO MFP_CFG(GPIO149, AF1) |
162 | #define GPIO150_GPIO150 MFP_CFG(GPIO150, AF1) | 162 | #define GPIO150_GPIO MFP_CFG(GPIO150, AF1) |
163 | #define GPIO151_GPIO151 MFP_CFG(GPIO151, AF1) | 163 | #define GPIO151_GPIO MFP_CFG(GPIO151, AF1) |
164 | #define GPIO152_GPIO152 MFP_CFG(GPIO152, AF1) | 164 | #define GPIO152_GPIO MFP_CFG(GPIO152, AF1) |
165 | #define GPIO153_GPIO153 MFP_CFG(GPIO153, AF1) | 165 | #define GPIO153_GPIO MFP_CFG(GPIO153, AF1) |
166 | #define GPIO154_GPIO154 MFP_CFG(GPIO154, AF1) | 166 | #define GPIO154_GPIO MFP_CFG(GPIO154, AF1) |
167 | #define GPIO155_GPIO155 MFP_CFG(GPIO155, AF1) | 167 | #define GPIO155_GPIO MFP_CFG(GPIO155, AF1) |
168 | #define GPIO156_GPIO156 MFP_CFG(GPIO156, AF1) | 168 | #define GPIO156_GPIO MFP_CFG(GPIO156, AF1) |
169 | #define GPIO157_GPIO157 MFP_CFG(GPIO157, AF1) | 169 | #define GPIO157_GPIO MFP_CFG(GPIO157, AF1) |
170 | #define GPIO158_GPIO158 MFP_CFG(GPIO158, AF1) | 170 | #define GPIO158_GPIO MFP_CFG(GPIO158, AF1) |
171 | #define GPIO159_GPIO159 MFP_CFG(GPIO159, AF1) | 171 | #define GPIO159_GPIO MFP_CFG(GPIO159, AF1) |
172 | #define GPIO160_GPIO160 MFP_CFG(GPIO160, AF1) | 172 | #define GPIO160_GPIO MFP_CFG(GPIO160, AF1) |
173 | #define GPIO161_GPIO161 MFP_CFG(GPIO161, AF1) | 173 | #define GPIO161_GPIO MFP_CFG(GPIO161, AF1) |
174 | #define GPIO162_GPIO162 MFP_CFG(GPIO162, AF1) | 174 | #define GPIO162_GPIO MFP_CFG(GPIO162, AF1) |
175 | #define GPIO163_GPIO163 MFP_CFG(GPIO163, AF1) | 175 | #define GPIO163_GPIO MFP_CFG(GPIO163, AF1) |
176 | #define GPIO164_GPIO164 MFP_CFG(GPIO164, AF1) | 176 | #define GPIO164_GPIO MFP_CFG(GPIO164, AF1) |
177 | #define GPIO165_GPIO165 MFP_CFG(GPIO165, AF1) | 177 | #define GPIO165_GPIO MFP_CFG(GPIO165, AF1) |
178 | #define GPIO166_GPIO166 MFP_CFG(GPIO166, AF1) | 178 | #define GPIO166_GPIO MFP_CFG(GPIO166, AF1) |
179 | #define GPIO167_GPIO167 MFP_CFG(GPIO167, AF1) | 179 | #define GPIO167_GPIO MFP_CFG(GPIO167, AF1) |
180 | #define GPIO168_GPIO168 MFP_CFG(GPIO168, AF1) | 180 | #define GPIO168_GPIO MFP_CFG(GPIO168, AF1) |
181 | 181 | ||
182 | /* DFI */ | 182 | /* DFI */ |
183 | #define GPIO108_DFI_D15 MFP_CFG(GPIO108, AF0) | 183 | #define GPIO108_DFI_D15 MFP_CFG(GPIO108, AF0) |
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h index dbba6e8a60c4..4aec493640b4 100644 --- a/arch/arm/mach-mmp/include/mach/mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mmp2.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef __ASM_MACH_MMP2_H | 1 | #ifndef __ASM_MACH_MMP2_H |
2 | #define __ASM_MACH_MMP2_H | 2 | #define __ASM_MACH_MMP2_H |
3 | 3 | ||
4 | #include <plat/sdhci.h> | ||
5 | |||
4 | struct sys_timer; | 6 | struct sys_timer; |
5 | 7 | ||
6 | extern struct sys_timer mmp2_timer; | 8 | extern struct sys_timer mmp2_timer; |
@@ -22,6 +24,10 @@ extern struct pxa_device_desc mmp2_device_twsi3; | |||
22 | extern struct pxa_device_desc mmp2_device_twsi4; | 24 | extern struct pxa_device_desc mmp2_device_twsi4; |
23 | extern struct pxa_device_desc mmp2_device_twsi5; | 25 | extern struct pxa_device_desc mmp2_device_twsi5; |
24 | extern struct pxa_device_desc mmp2_device_twsi6; | 26 | extern struct pxa_device_desc mmp2_device_twsi6; |
27 | extern struct pxa_device_desc mmp2_device_sdh0; | ||
28 | extern struct pxa_device_desc mmp2_device_sdh1; | ||
29 | extern struct pxa_device_desc mmp2_device_sdh2; | ||
30 | extern struct pxa_device_desc mmp2_device_sdh3; | ||
25 | 31 | ||
26 | static inline int mmp2_add_uart(int id) | 32 | static inline int mmp2_add_uart(int id) |
27 | { | 33 | { |
@@ -63,5 +69,21 @@ static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data, | |||
63 | return pxa_register_device(d, data, sizeof(*data)); | 69 | return pxa_register_device(d, data, sizeof(*data)); |
64 | } | 70 | } |
65 | 71 | ||
72 | static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data) | ||
73 | { | ||
74 | struct pxa_device_desc *d = NULL; | ||
75 | |||
76 | switch (id) { | ||
77 | case 0: d = &mmp2_device_sdh0; break; | ||
78 | case 1: d = &mmp2_device_sdh1; break; | ||
79 | case 2: d = &mmp2_device_sdh2; break; | ||
80 | case 3: d = &mmp2_device_sdh3; break; | ||
81 | default: | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | |||
85 | return pxa_register_device(d, data, sizeof(*data)); | ||
86 | } | ||
87 | |||
66 | #endif /* __ASM_MACH_MMP2_H */ | 88 | #endif /* __ASM_MACH_MMP2_H */ |
67 | 89 | ||
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h index ac4702357a6e..f7011ef70bf5 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apmu.h +++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #define APMU_DMA APMU_REG(0x064) | 27 | #define APMU_DMA APMU_REG(0x064) |
28 | #define APMU_GEU APMU_REG(0x068) | 28 | #define APMU_GEU APMU_REG(0x068) |
29 | #define APMU_BUS APMU_REG(0x06c) | 29 | #define APMU_BUS APMU_REG(0x06c) |
30 | #define APMU_SDH2 APMU_REG(0x0e8) | ||
31 | #define APMU_SDH3 APMU_REG(0x0ec) | ||
30 | 32 | ||
31 | #define APMU_FNCLK_EN (1 << 4) | 33 | #define APMU_FNCLK_EN (1 << 4) |
32 | #define APMU_AXICLK_EN (1 << 3) | 34 | #define APMU_AXICLK_EN (1 << 3) |
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c index 2a684fa50773..24172a0aad59 100644 --- a/arch/arm/mach-mmp/jasper.c +++ b/arch/arm/mach-mmp/jasper.c | |||
@@ -67,6 +67,36 @@ static unsigned long jasper_pin_config[] __initdata = { | |||
67 | 67 | ||
68 | /* PMIC */ | 68 | /* PMIC */ |
69 | PMIC_PMIC_INT | MFP_LPM_EDGE_FALL, | 69 | PMIC_PMIC_INT | MFP_LPM_EDGE_FALL, |
70 | |||
71 | /* MMC1 */ | ||
72 | GPIO131_MMC1_DAT3, | ||
73 | GPIO132_MMC1_DAT2, | ||
74 | GPIO133_MMC1_DAT1, | ||
75 | GPIO134_MMC1_DAT0, | ||
76 | GPIO136_MMC1_CMD, | ||
77 | GPIO139_MMC1_CLK, | ||
78 | GPIO140_MMC1_CD, | ||
79 | GPIO141_MMC1_WP, | ||
80 | |||
81 | /* MMC2 */ | ||
82 | GPIO37_MMC2_DAT3, | ||
83 | GPIO38_MMC2_DAT2, | ||
84 | GPIO39_MMC2_DAT1, | ||
85 | GPIO40_MMC2_DAT0, | ||
86 | GPIO41_MMC2_CMD, | ||
87 | GPIO42_MMC2_CLK, | ||
88 | |||
89 | /* MMC3 */ | ||
90 | GPIO165_MMC3_DAT7, | ||
91 | GPIO162_MMC3_DAT6, | ||
92 | GPIO166_MMC3_DAT5, | ||
93 | GPIO163_MMC3_DAT4, | ||
94 | GPIO167_MMC3_DAT3, | ||
95 | GPIO164_MMC3_DAT2, | ||
96 | GPIO168_MMC3_DAT1, | ||
97 | GPIO111_MMC3_DAT0, | ||
98 | GPIO112_MMC3_CMD, | ||
99 | GPIO151_MMC3_CLK, | ||
70 | }; | 100 | }; |
71 | 101 | ||
72 | static struct regulator_consumer_supply max8649_supply[] = { | 102 | static struct regulator_consumer_supply max8649_supply[] = { |
@@ -123,6 +153,10 @@ static struct i2c_board_info jasper_twsi1_info[] = { | |||
123 | }, | 153 | }, |
124 | }; | 154 | }; |
125 | 155 | ||
156 | static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { | ||
157 | .max_speed = 25000000, | ||
158 | }; | ||
159 | |||
126 | static void __init jasper_init(void) | 160 | static void __init jasper_init(void) |
127 | { | 161 | { |
128 | mfp_config(ARRAY_AND_SIZE(jasper_pin_config)); | 162 | mfp_config(ARRAY_AND_SIZE(jasper_pin_config)); |
@@ -131,6 +165,7 @@ static void __init jasper_init(void) | |||
131 | mmp2_add_uart(1); | 165 | mmp2_add_uart(1); |
132 | mmp2_add_uart(3); | 166 | mmp2_add_uart(3); |
133 | mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info)); | 167 | mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info)); |
168 | mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ | ||
134 | 169 | ||
135 | regulator_has_full_constraints(); | 170 | regulator_has_full_constraints(); |
136 | } | 171 | } |
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index daf3993349f8..8e6c3ac7f7c1 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c | |||
@@ -115,6 +115,29 @@ void __init mmp2_init_irq(void) | |||
115 | mmp2_init_gpio(); | 115 | mmp2_init_gpio(); |
116 | } | 116 | } |
117 | 117 | ||
118 | static void sdhc_clk_enable(struct clk *clk) | ||
119 | { | ||
120 | uint32_t clk_rst; | ||
121 | |||
122 | clk_rst = __raw_readl(clk->clk_rst); | ||
123 | clk_rst |= clk->enable_val; | ||
124 | __raw_writel(clk_rst, clk->clk_rst); | ||
125 | } | ||
126 | |||
127 | static void sdhc_clk_disable(struct clk *clk) | ||
128 | { | ||
129 | uint32_t clk_rst; | ||
130 | |||
131 | clk_rst = __raw_readl(clk->clk_rst); | ||
132 | clk_rst &= ~clk->enable_val; | ||
133 | __raw_writel(clk_rst, clk->clk_rst); | ||
134 | } | ||
135 | |||
136 | struct clkops sdhc_clk_ops = { | ||
137 | .enable = sdhc_clk_enable, | ||
138 | .disable = sdhc_clk_disable, | ||
139 | }; | ||
140 | |||
118 | /* APB peripheral clocks */ | 141 | /* APB peripheral clocks */ |
119 | static APBC_CLK(uart1, MMP2_UART1, 1, 26000000); | 142 | static APBC_CLK(uart1, MMP2_UART1, 1, 26000000); |
120 | static APBC_CLK(uart2, MMP2_UART2, 1, 26000000); | 143 | static APBC_CLK(uart2, MMP2_UART2, 1, 26000000); |
@@ -126,9 +149,12 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000); | |||
126 | static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); | 149 | static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); |
127 | static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); | 150 | static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); |
128 | static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); | 151 | static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); |
129 | static APBC_CLK(rtc, MMP2_RTC, 0, 32768); | ||
130 | 152 | ||
131 | static APMU_CLK(nand, NAND, 0xbf, 100000000); | 153 | static APMU_CLK(nand, NAND, 0xbf, 100000000); |
154 | static APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops); | ||
155 | static APMU_CLK_OPS(sdh1, SDH1, 0x1b, 200000000, &sdhc_clk_ops); | ||
156 | static APMU_CLK_OPS(sdh2, SDH2, 0x1b, 200000000, &sdhc_clk_ops); | ||
157 | static APMU_CLK_OPS(sdh3, SDH3, 0x1b, 200000000, &sdhc_clk_ops); | ||
132 | 158 | ||
133 | static struct clk_lookup mmp2_clkregs[] = { | 159 | static struct clk_lookup mmp2_clkregs[] = { |
134 | INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL), | 160 | INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL), |
@@ -142,6 +168,10 @@ static struct clk_lookup mmp2_clkregs[] = { | |||
142 | INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL), | 168 | INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL), |
143 | INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL), | 169 | INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL), |
144 | INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), | 170 | INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), |
171 | INIT_CLKREG(&clk_sdh0, "sdhci-pxa.0", "PXA-SDHCLK"), | ||
172 | INIT_CLKREG(&clk_sdh1, "sdhci-pxa.1", "PXA-SDHCLK"), | ||
173 | INIT_CLKREG(&clk_sdh2, "sdhci-pxa.2", "PXA-SDHCLK"), | ||
174 | INIT_CLKREG(&clk_sdh3, "sdhci-pxa.3", "PXA-SDHCLK"), | ||
145 | }; | 175 | }; |
146 | 176 | ||
147 | static int __init mmp2_init(void) | 177 | static int __init mmp2_init(void) |
@@ -192,4 +222,8 @@ MMP2_DEVICE(twsi4, "pxa2xx-i2c", 3, TWSI4, 0xd4033000, 0x70); | |||
192 | MMP2_DEVICE(twsi5, "pxa2xx-i2c", 4, TWSI5, 0xd4033800, 0x70); | 222 | MMP2_DEVICE(twsi5, "pxa2xx-i2c", 4, TWSI5, 0xd4033800, 0x70); |
193 | MMP2_DEVICE(twsi6, "pxa2xx-i2c", 5, TWSI6, 0xd4034000, 0x70); | 223 | MMP2_DEVICE(twsi6, "pxa2xx-i2c", 5, TWSI6, 0xd4034000, 0x70); |
194 | MMP2_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x100, 28, 29); | 224 | MMP2_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x100, 28, 29); |
225 | MMP2_DEVICE(sdh0, "sdhci-pxa", 0, MMC, 0xd4280000, 0x120); | ||
226 | MMP2_DEVICE(sdh1, "sdhci-pxa", 1, MMC2, 0xd4280800, 0x120); | ||
227 | MMP2_DEVICE(sdh2, "sdhci-pxa", 2, MMC3, 0xd4281000, 0x120); | ||
228 | MMP2_DEVICE(sdh3, "sdhci-pxa", 3, MMC4, 0xd4281800, 0x120); | ||
195 | 229 | ||
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index 46f2d69bef3c..8f92ccd26edf 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c | |||
@@ -111,6 +111,7 @@ static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000); | |||
111 | static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); | 111 | static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); |
112 | 112 | ||
113 | static APMU_CLK(nand, NAND, 0x01db, 208000000); | 113 | static APMU_CLK(nand, NAND, 0x01db, 208000000); |
114 | static APMU_CLK(u2o, USB, 0x1b, 480000000); | ||
114 | 115 | ||
115 | /* device and clock bindings */ | 116 | /* device and clock bindings */ |
116 | static struct clk_lookup pxa910_clkregs[] = { | 117 | static struct clk_lookup pxa910_clkregs[] = { |
@@ -123,6 +124,7 @@ static struct clk_lookup pxa910_clkregs[] = { | |||
123 | INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL), | 124 | INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL), |
124 | INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL), | 125 | INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL), |
125 | INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), | 126 | INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), |
127 | INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"), | ||
126 | }; | 128 | }; |
127 | 129 | ||
128 | static int __init pxa910_init(void) | 130 | static int __init pxa910_init(void) |
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index dbbcfeb919db..31e5fd63ec9a 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig | |||
@@ -49,6 +49,8 @@ endchoice | |||
49 | 49 | ||
50 | config MSM_SOC_REV_A | 50 | config MSM_SOC_REV_A |
51 | bool | 51 | bool |
52 | config ARCH_MSM_SCORPIONMP | ||
53 | bool | ||
52 | 54 | ||
53 | config ARCH_MSM_ARM11 | 55 | config ARCH_MSM_ARM11 |
54 | bool | 56 | bool |
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h index 788bdace1304..3eff39921d4d 100644 --- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h +++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h | |||
@@ -65,7 +65,7 @@ | |||
65 | */ | 65 | */ |
66 | #define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x00000) | 66 | #define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x00000) |
67 | #define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE | 0x1500) | 67 | #define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE | 0x1500) |
68 | #define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE | 0x1700) | 68 | #define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE | 0x1570) |
69 | 69 | ||
70 | #define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x10000) | 70 | #define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x10000) |
71 | #define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x10000) | 71 | #define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x10000) |
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 86c9b2102952..9db9203667df 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c | |||
@@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = { | |||
216 | { | 216 | { |
217 | .name = "wl1271", | 217 | .name = "wl1271", |
218 | .mmc = 3, | 218 | .mmc = 3, |
219 | .caps = MMC_CAP_4_BIT_DATA, | 219 | .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, |
220 | .gpio_wp = -EINVAL, | 220 | .gpio_wp = -EINVAL, |
221 | .gpio_cd = -EINVAL, | 221 | .gpio_cd = -EINVAL, |
222 | .nonremovable = true, | 222 | .nonremovable = true, |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 40562ddd3ee4..a1939b1e6f82 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -297,7 +297,7 @@ static int __init _omap2_init_reprogram_sdrc(void) | |||
297 | return 0; | 297 | return 0; |
298 | 298 | ||
299 | dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); | 299 | dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); |
300 | if (!dpll3_m2_ck) | 300 | if (IS_ERR(dpll3_m2_ck)) |
301 | return -EINVAL; | 301 | return -EINVAL; |
302 | 302 | ||
303 | rate = clk_get_rate(dpll3_m2_ck); | 303 | rate = clk_get_rate(dpll3_m2_ck); |
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 5e81517a7af2..a8afb610c7d8 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -161,6 +161,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us) | |||
161 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); | 161 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); |
162 | } | 162 | } |
163 | 163 | ||
164 | void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) | ||
165 | { | ||
166 | u32 tick_rate, cycles; | ||
167 | |||
168 | if (!seconds && !milliseconds) | ||
169 | return; | ||
170 | |||
171 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
172 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; | ||
173 | omap_dm_timer_stop(gptimer_wakeup); | ||
174 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
175 | |||
176 | pr_info("PM: Resume timer in %u.%03u secs" | ||
177 | " (%d ticks at %d ticks/sec.)\n", | ||
178 | seconds, milliseconds, cycles, tick_rate); | ||
179 | } | ||
180 | |||
164 | #ifdef CONFIG_DEBUG_FS | 181 | #ifdef CONFIG_DEBUG_FS |
165 | #include <linux/debugfs.h> | 182 | #include <linux/debugfs.h> |
166 | #include <linux/seq_file.h> | 183 | #include <linux/seq_file.h> |
@@ -354,23 +371,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) | |||
354 | pwrdm->timer = t; | 371 | pwrdm->timer = t; |
355 | } | 372 | } |
356 | 373 | ||
357 | void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) | ||
358 | { | ||
359 | u32 tick_rate, cycles; | ||
360 | |||
361 | if (!seconds && !milliseconds) | ||
362 | return; | ||
363 | |||
364 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
365 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; | ||
366 | omap_dm_timer_stop(gptimer_wakeup); | ||
367 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
368 | |||
369 | pr_info("PM: Resume timer in %u.%03u secs" | ||
370 | " (%d ticks at %d ticks/sec.)\n", | ||
371 | seconds, milliseconds, cycles, tick_rate); | ||
372 | } | ||
373 | |||
374 | static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) | 374 | static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) |
375 | { | 375 | { |
376 | struct seq_file *s = (struct seq_file *)user; | 376 | struct seq_file *s = (struct seq_file *)user; |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c85923e56b85..aaeea49b9bdd 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -53,6 +53,19 @@ | |||
53 | #include <plat/powerdomain.h> | 53 | #include <plat/powerdomain.h> |
54 | #include <plat/clockdomain.h> | 54 | #include <plat/clockdomain.h> |
55 | 55 | ||
56 | #ifdef CONFIG_SUSPEND | ||
57 | static suspend_state_t suspend_state = PM_SUSPEND_ON; | ||
58 | static inline bool is_suspending(void) | ||
59 | { | ||
60 | return (suspend_state != PM_SUSPEND_ON); | ||
61 | } | ||
62 | #else | ||
63 | static inline bool is_suspending(void) | ||
64 | { | ||
65 | return false; | ||
66 | } | ||
67 | #endif | ||
68 | |||
56 | static void (*omap2_sram_idle)(void); | 69 | static void (*omap2_sram_idle)(void); |
57 | static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, | 70 | static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, |
58 | void __iomem *sdrc_power); | 71 | void __iomem *sdrc_power); |
@@ -120,8 +133,9 @@ static void omap2_enter_full_retention(void) | |||
120 | goto no_sleep; | 133 | goto no_sleep; |
121 | 134 | ||
122 | /* Block console output in case it is on one of the OMAP UARTs */ | 135 | /* Block console output in case it is on one of the OMAP UARTs */ |
123 | if (try_acquire_console_sem()) | 136 | if (!is_suspending()) |
124 | goto no_sleep; | 137 | if (try_acquire_console_sem()) |
138 | goto no_sleep; | ||
125 | 139 | ||
126 | omap_uart_prepare_idle(0); | 140 | omap_uart_prepare_idle(0); |
127 | omap_uart_prepare_idle(1); | 141 | omap_uart_prepare_idle(1); |
@@ -136,7 +150,8 @@ static void omap2_enter_full_retention(void) | |||
136 | omap_uart_resume_idle(1); | 150 | omap_uart_resume_idle(1); |
137 | omap_uart_resume_idle(0); | 151 | omap_uart_resume_idle(0); |
138 | 152 | ||
139 | release_console_sem(); | 153 | if (!is_suspending()) |
154 | release_console_sem(); | ||
140 | 155 | ||
141 | no_sleep: | 156 | no_sleep: |
142 | if (omap2_pm_debug) { | 157 | if (omap2_pm_debug) { |
@@ -284,6 +299,12 @@ out: | |||
284 | local_irq_enable(); | 299 | local_irq_enable(); |
285 | } | 300 | } |
286 | 301 | ||
302 | static int omap2_pm_begin(suspend_state_t state) | ||
303 | { | ||
304 | suspend_state = state; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
287 | static int omap2_pm_prepare(void) | 308 | static int omap2_pm_prepare(void) |
288 | { | 309 | { |
289 | /* We cannot sleep in idle until we have resumed */ | 310 | /* We cannot sleep in idle until we have resumed */ |
@@ -333,10 +354,17 @@ static void omap2_pm_finish(void) | |||
333 | enable_hlt(); | 354 | enable_hlt(); |
334 | } | 355 | } |
335 | 356 | ||
357 | static void omap2_pm_end(void) | ||
358 | { | ||
359 | suspend_state = PM_SUSPEND_ON; | ||
360 | } | ||
361 | |||
336 | static struct platform_suspend_ops omap_pm_ops = { | 362 | static struct platform_suspend_ops omap_pm_ops = { |
363 | .begin = omap2_pm_begin, | ||
337 | .prepare = omap2_pm_prepare, | 364 | .prepare = omap2_pm_prepare, |
338 | .enter = omap2_pm_enter, | 365 | .enter = omap2_pm_enter, |
339 | .finish = omap2_pm_finish, | 366 | .finish = omap2_pm_finish, |
367 | .end = omap2_pm_end, | ||
340 | .valid = suspend_valid_only_mem, | 368 | .valid = suspend_valid_only_mem, |
341 | }; | 369 | }; |
342 | 370 | ||
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0ec8a04b7473..648b8c50d024 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -50,6 +50,19 @@ | |||
50 | #include "sdrc.h" | 50 | #include "sdrc.h" |
51 | #include "control.h" | 51 | #include "control.h" |
52 | 52 | ||
53 | #ifdef CONFIG_SUSPEND | ||
54 | static suspend_state_t suspend_state = PM_SUSPEND_ON; | ||
55 | static inline bool is_suspending(void) | ||
56 | { | ||
57 | return (suspend_state != PM_SUSPEND_ON); | ||
58 | } | ||
59 | #else | ||
60 | static inline bool is_suspending(void) | ||
61 | { | ||
62 | return false; | ||
63 | } | ||
64 | #endif | ||
65 | |||
53 | /* Scratchpad offsets */ | 66 | /* Scratchpad offsets */ |
54 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 | 67 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 |
55 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 | 68 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 |
@@ -387,10 +400,11 @@ void omap_sram_idle(void) | |||
387 | } | 400 | } |
388 | 401 | ||
389 | /* Block console output in case it is on one of the OMAP UARTs */ | 402 | /* Block console output in case it is on one of the OMAP UARTs */ |
390 | if (per_next_state < PWRDM_POWER_ON || | 403 | if (!is_suspending()) |
391 | core_next_state < PWRDM_POWER_ON) | 404 | if (per_next_state < PWRDM_POWER_ON || |
392 | if (try_acquire_console_sem()) | 405 | core_next_state < PWRDM_POWER_ON) |
393 | goto console_still_active; | 406 | if (try_acquire_console_sem()) |
407 | goto console_still_active; | ||
394 | 408 | ||
395 | /* PER */ | 409 | /* PER */ |
396 | if (per_next_state < PWRDM_POWER_ON) { | 410 | if (per_next_state < PWRDM_POWER_ON) { |
@@ -470,7 +484,8 @@ void omap_sram_idle(void) | |||
470 | omap_uart_resume_idle(3); | 484 | omap_uart_resume_idle(3); |
471 | } | 485 | } |
472 | 486 | ||
473 | release_console_sem(); | 487 | if (!is_suspending()) |
488 | release_console_sem(); | ||
474 | 489 | ||
475 | console_still_active: | 490 | console_still_active: |
476 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 491 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
@@ -514,8 +529,6 @@ out: | |||
514 | } | 529 | } |
515 | 530 | ||
516 | #ifdef CONFIG_SUSPEND | 531 | #ifdef CONFIG_SUSPEND |
517 | static suspend_state_t suspend_state; | ||
518 | |||
519 | static int omap3_pm_prepare(void) | 532 | static int omap3_pm_prepare(void) |
520 | { | 533 | { |
521 | disable_hlt(); | 534 | disable_hlt(); |
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 298a22a754e2..f81acee4738d 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h | |||
@@ -243,13 +243,14 @@ | |||
243 | #define OMAP24XX_EN_GPT1_MASK (1 << 0) | 243 | #define OMAP24XX_EN_GPT1_MASK (1 << 0) |
244 | 244 | ||
245 | /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ | 245 | /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ |
246 | #define OMAP24XX_ST_GPIOS_SHIFT (1 << 2) | 246 | #define OMAP24XX_ST_GPIOS_SHIFT 2 |
247 | #define OMAP24XX_ST_GPIOS_MASK 2 | 247 | #define OMAP24XX_ST_GPIOS_MASK (1 << 2) |
248 | #define OMAP24XX_ST_GPT1_SHIFT (1 << 0) | 248 | #define OMAP24XX_ST_GPT1_SHIFT 0 |
249 | #define OMAP24XX_ST_GPT1_MASK 0 | 249 | #define OMAP24XX_ST_GPT1_MASK (1 << 0) |
250 | 250 | ||
251 | /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ | 251 | /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ |
252 | #define OMAP2430_ST_MDM_SHIFT (1 << 0) | 252 | #define OMAP2430_ST_MDM_SHIFT 0 |
253 | #define OMAP2430_ST_MDM_MASK (1 << 0) | ||
253 | 254 | ||
254 | 255 | ||
255 | /* 3430 register bits shared between CM & PRM registers */ | 256 | /* 3430 register bits shared between CM & PRM registers */ |
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index c897e03e413d..6604fc6ca58a 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig | |||
@@ -51,6 +51,13 @@ config MACH_LINKSTATION_PRO | |||
51 | Buffalo Linkstation Pro/Live platform. Both v1 and | 51 | Buffalo Linkstation Pro/Live platform. Both v1 and |
52 | v2 devices are supported. | 52 | v2 devices are supported. |
53 | 53 | ||
54 | config MACH_LINKSTATION_LSCHL | ||
55 | bool "Buffalo Linkstation Live v3 (LS-CHL)" | ||
56 | select I2C_BOARDINFO | ||
57 | help | ||
58 | Say 'Y' here if you want your kernel to support the | ||
59 | Buffalo Linkstation Live v3 (LS-CHL) platform. | ||
60 | |||
54 | config MACH_LINKSTATION_MINI | 61 | config MACH_LINKSTATION_MINI |
55 | bool "Buffalo Linkstation Mini" | 62 | bool "Buffalo Linkstation Mini" |
56 | select I2C_BOARDINFO | 63 | select I2C_BOARDINFO |
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index eb6eabcb41e4..7f18cdacd487 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile | |||
@@ -21,3 +21,4 @@ obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o | |||
21 | obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o | 21 | obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o |
22 | obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o | 22 | obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o |
23 | obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o | 23 | obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o |
24 | obj-$(CONFIG_MACH_LINKSTATION_LSCHL) += ls-chl-setup.o | ||
diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c new file mode 100644 index 000000000000..20a9b66cbafa --- /dev/null +++ b/arch/arm/mach-orion5x/ls-chl-setup.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/ls-chl-setup.c | ||
3 | * | ||
4 | * Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/mtd/physmap.h> | ||
15 | #include <linux/mv643xx_eth.h> | ||
16 | #include <linux/leds.h> | ||
17 | #include <linux/gpio_keys.h> | ||
18 | #include <linux/gpio-fan.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/ata_platform.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <asm/mach-types.h> | ||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/system.h> | ||
26 | #include <mach/orion5x.h> | ||
27 | #include "common.h" | ||
28 | #include "mpp.h" | ||
29 | |||
30 | /***************************************************************************** | ||
31 | * Linkstation LS-CHL Info | ||
32 | ****************************************************************************/ | ||
33 | |||
34 | /* | ||
35 | * 256K NOR flash Device bus boot chip select | ||
36 | */ | ||
37 | |||
38 | #define LSCHL_NOR_BOOT_BASE 0xf4000000 | ||
39 | #define LSCHL_NOR_BOOT_SIZE SZ_256K | ||
40 | |||
41 | /***************************************************************************** | ||
42 | * 256KB NOR Flash on BOOT Device | ||
43 | ****************************************************************************/ | ||
44 | |||
45 | static struct physmap_flash_data lschl_nor_flash_data = { | ||
46 | .width = 1, | ||
47 | }; | ||
48 | |||
49 | static struct resource lschl_nor_flash_resource = { | ||
50 | .flags = IORESOURCE_MEM, | ||
51 | .start = LSCHL_NOR_BOOT_BASE, | ||
52 | .end = LSCHL_NOR_BOOT_BASE + LSCHL_NOR_BOOT_SIZE - 1, | ||
53 | }; | ||
54 | |||
55 | static struct platform_device lschl_nor_flash = { | ||
56 | .name = "physmap-flash", | ||
57 | .id = 0, | ||
58 | .dev = { | ||
59 | .platform_data = &lschl_nor_flash_data, | ||
60 | }, | ||
61 | .num_resources = 1, | ||
62 | .resource = &lschl_nor_flash_resource, | ||
63 | }; | ||
64 | |||
65 | /***************************************************************************** | ||
66 | * Ethernet | ||
67 | ****************************************************************************/ | ||
68 | |||
69 | static struct mv643xx_eth_platform_data lschl_eth_data = { | ||
70 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
71 | }; | ||
72 | |||
73 | /***************************************************************************** | ||
74 | * RTC 5C372a on I2C bus | ||
75 | ****************************************************************************/ | ||
76 | |||
77 | static struct i2c_board_info __initdata lschl_i2c_rtc = { | ||
78 | I2C_BOARD_INFO("rs5c372a", 0x32), | ||
79 | }; | ||
80 | |||
81 | /***************************************************************************** | ||
82 | * LEDs attached to GPIO | ||
83 | ****************************************************************************/ | ||
84 | |||
85 | #define LSCHL_GPIO_LED_ALARM 2 | ||
86 | #define LSCHL_GPIO_LED_INFO 3 | ||
87 | #define LSCHL_GPIO_LED_FUNC 17 | ||
88 | #define LSCHL_GPIO_LED_PWR 0 | ||
89 | |||
90 | static struct gpio_led lschl_led_pins[] = { | ||
91 | { | ||
92 | .name = "alarm:red", | ||
93 | .gpio = LSCHL_GPIO_LED_ALARM, | ||
94 | .active_low = 1, | ||
95 | }, { | ||
96 | .name = "info:amber", | ||
97 | .gpio = LSCHL_GPIO_LED_INFO, | ||
98 | .active_low = 1, | ||
99 | }, { | ||
100 | .name = "func:blue:top", | ||
101 | .gpio = LSCHL_GPIO_LED_FUNC, | ||
102 | .active_low = 1, | ||
103 | }, { | ||
104 | .name = "power:blue:bottom", | ||
105 | .gpio = LSCHL_GPIO_LED_PWR, | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | static struct gpio_led_platform_data lschl_led_data = { | ||
110 | .leds = lschl_led_pins, | ||
111 | .num_leds = ARRAY_SIZE(lschl_led_pins), | ||
112 | }; | ||
113 | |||
114 | static struct platform_device lschl_leds = { | ||
115 | .name = "leds-gpio", | ||
116 | .id = -1, | ||
117 | .dev = { | ||
118 | .platform_data = &lschl_led_data, | ||
119 | }, | ||
120 | }; | ||
121 | |||
122 | /***************************************************************************** | ||
123 | * SATA | ||
124 | ****************************************************************************/ | ||
125 | static struct mv_sata_platform_data lschl_sata_data = { | ||
126 | .n_ports = 2, | ||
127 | }; | ||
128 | |||
129 | /***************************************************************************** | ||
130 | * LS-CHL specific power off method: reboot | ||
131 | ****************************************************************************/ | ||
132 | /* | ||
133 | * On the LS-CHL, the shutdown process is following: | ||
134 | * - Userland monitors key events until the power switch goes to off position | ||
135 | * - The board reboots | ||
136 | * - U-boot starts and goes into an idle mode waiting for the user | ||
137 | * to move the switch to ON position | ||
138 | * | ||
139 | */ | ||
140 | |||
141 | static void lschl_power_off(void) | ||
142 | { | ||
143 | arm_machine_restart('h', NULL); | ||
144 | } | ||
145 | |||
146 | /***************************************************************************** | ||
147 | * General Setup | ||
148 | ****************************************************************************/ | ||
149 | #define LSCHL_GPIO_USB_POWER 9 | ||
150 | #define LSCHL_GPIO_AUTO_POWER 17 | ||
151 | #define LSCHL_GPIO_POWER 18 | ||
152 | |||
153 | /**************************************************************************** | ||
154 | * GPIO Attached Keys | ||
155 | ****************************************************************************/ | ||
156 | #define LSCHL_GPIO_KEY_FUNC 15 | ||
157 | #define LSCHL_GPIO_KEY_POWER 8 | ||
158 | #define LSCHL_GPIO_KEY_AUTOPOWER 10 | ||
159 | #define LSCHL_SW_POWER 0x00 | ||
160 | #define LSCHL_SW_AUTOPOWER 0x01 | ||
161 | #define LSCHL_SW_FUNC 0x02 | ||
162 | |||
163 | static struct gpio_keys_button lschl_buttons[] = { | ||
164 | { | ||
165 | .type = EV_SW, | ||
166 | .code = LSCHL_SW_POWER, | ||
167 | .gpio = LSCHL_GPIO_KEY_POWER, | ||
168 | .desc = "Power-on Switch", | ||
169 | .active_low = 1, | ||
170 | }, { | ||
171 | .type = EV_SW, | ||
172 | .code = LSCHL_SW_AUTOPOWER, | ||
173 | .gpio = LSCHL_GPIO_KEY_AUTOPOWER, | ||
174 | .desc = "Power-auto Switch", | ||
175 | .active_low = 1, | ||
176 | }, { | ||
177 | .type = EV_SW, | ||
178 | .code = LSCHL_SW_FUNC, | ||
179 | .gpio = LSCHL_GPIO_KEY_FUNC, | ||
180 | .desc = "Function Switch", | ||
181 | .active_low = 1, | ||
182 | }, | ||
183 | }; | ||
184 | |||
185 | static struct gpio_keys_platform_data lschl_button_data = { | ||
186 | .buttons = lschl_buttons, | ||
187 | .nbuttons = ARRAY_SIZE(lschl_buttons), | ||
188 | }; | ||
189 | |||
190 | static struct platform_device lschl_button_device = { | ||
191 | .name = "gpio-keys", | ||
192 | .id = -1, | ||
193 | .num_resources = 0, | ||
194 | .dev = { | ||
195 | .platform_data = &lschl_button_data, | ||
196 | }, | ||
197 | }; | ||
198 | |||
199 | #define LSCHL_GPIO_HDD_POWER 1 | ||
200 | |||
201 | /**************************************************************************** | ||
202 | * GPIO Fan | ||
203 | ****************************************************************************/ | ||
204 | |||
205 | #define LSCHL_GPIO_FAN_LOW 16 | ||
206 | #define LSCHL_GPIO_FAN_HIGH 14 | ||
207 | #define LSCHL_GPIO_FAN_LOCK 6 | ||
208 | |||
209 | static struct gpio_fan_alarm lschl_alarm = { | ||
210 | .gpio = LSCHL_GPIO_FAN_LOCK, | ||
211 | }; | ||
212 | |||
213 | static struct gpio_fan_speed lschl_speeds[] = { | ||
214 | { | ||
215 | .rpm = 0, | ||
216 | .ctrl_val = 3, | ||
217 | }, { | ||
218 | .rpm = 1500, | ||
219 | .ctrl_val = 2, | ||
220 | }, { | ||
221 | .rpm = 3250, | ||
222 | .ctrl_val = 1, | ||
223 | }, { | ||
224 | .rpm = 5000, | ||
225 | .ctrl_val = 0, | ||
226 | }, | ||
227 | }; | ||
228 | |||
229 | static int lschl_gpio_list[] = { | ||
230 | LSCHL_GPIO_FAN_HIGH, LSCHL_GPIO_FAN_LOW, | ||
231 | }; | ||
232 | |||
233 | static struct gpio_fan_platform_data lschl_fan_data = { | ||
234 | .num_ctrl = ARRAY_SIZE(lschl_gpio_list), | ||
235 | .ctrl = lschl_gpio_list, | ||
236 | .alarm = &lschl_alarm, | ||
237 | .num_speed = ARRAY_SIZE(lschl_speeds), | ||
238 | .speed = lschl_speeds, | ||
239 | }; | ||
240 | |||
241 | static struct platform_device lschl_fan_device = { | ||
242 | .name = "gpio-fan", | ||
243 | .id = -1, | ||
244 | .num_resources = 0, | ||
245 | .dev = { | ||
246 | .platform_data = &lschl_fan_data, | ||
247 | }, | ||
248 | }; | ||
249 | |||
250 | /**************************************************************************** | ||
251 | * GPIO Data | ||
252 | ****************************************************************************/ | ||
253 | |||
254 | static struct orion5x_mpp_mode lschl_mpp_modes[] __initdata = { | ||
255 | { 0, MPP_GPIO }, /* LED POWER */ | ||
256 | { 1, MPP_GPIO }, /* HDD POWER */ | ||
257 | { 2, MPP_GPIO }, /* LED ALARM */ | ||
258 | { 3, MPP_GPIO }, /* LED INFO */ | ||
259 | { 4, MPP_UNUSED }, | ||
260 | { 5, MPP_UNUSED }, | ||
261 | { 6, MPP_GPIO }, /* FAN LOCK */ | ||
262 | { 7, MPP_GPIO }, /* SW INIT */ | ||
263 | { 8, MPP_GPIO }, /* SW POWER */ | ||
264 | { 9, MPP_GPIO }, /* USB POWER */ | ||
265 | { 10, MPP_GPIO }, /* SW AUTO POWER */ | ||
266 | { 11, MPP_UNUSED }, | ||
267 | { 12, MPP_UNUSED }, | ||
268 | { 13, MPP_UNUSED }, | ||
269 | { 14, MPP_GPIO }, /* FAN HIGH */ | ||
270 | { 15, MPP_GPIO }, /* SW FUNC */ | ||
271 | { 16, MPP_GPIO }, /* FAN LOW */ | ||
272 | { 17, MPP_GPIO }, /* LED FUNC */ | ||
273 | { 18, MPP_UNUSED }, | ||
274 | { 19, MPP_UNUSED }, | ||
275 | { -1 }, | ||
276 | }; | ||
277 | |||
278 | static void __init lschl_init(void) | ||
279 | { | ||
280 | /* | ||
281 | * Setup basic Orion functions. Needs to be called early. | ||
282 | */ | ||
283 | orion5x_init(); | ||
284 | |||
285 | orion5x_mpp_conf(lschl_mpp_modes); | ||
286 | |||
287 | /* | ||
288 | * Configure peripherals. | ||
289 | */ | ||
290 | orion5x_ehci0_init(); | ||
291 | orion5x_ehci1_init(); | ||
292 | orion5x_eth_init(&lschl_eth_data); | ||
293 | orion5x_i2c_init(); | ||
294 | orion5x_sata_init(&lschl_sata_data); | ||
295 | orion5x_uart0_init(); | ||
296 | orion5x_xor_init(); | ||
297 | |||
298 | orion5x_setup_dev_boot_win(LSCHL_NOR_BOOT_BASE, | ||
299 | LSCHL_NOR_BOOT_SIZE); | ||
300 | platform_device_register(&lschl_nor_flash); | ||
301 | |||
302 | platform_device_register(&lschl_leds); | ||
303 | |||
304 | platform_device_register(&lschl_button_device); | ||
305 | |||
306 | platform_device_register(&lschl_fan_device); | ||
307 | |||
308 | i2c_register_board_info(0, &lschl_i2c_rtc, 1); | ||
309 | |||
310 | /* usb power on */ | ||
311 | gpio_set_value(LSCHL_GPIO_USB_POWER, 1); | ||
312 | |||
313 | /* register power-off method */ | ||
314 | pm_power_off = lschl_power_off; | ||
315 | |||
316 | pr_info("%s: finished\n", __func__); | ||
317 | } | ||
318 | |||
319 | MACHINE_START(LINKSTATION_LSCHL, "Buffalo Linkstation LiveV3 (LS-CHL)") | ||
320 | /* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> */ | ||
321 | .boot_params = 0x00000100, | ||
322 | .init_machine = lschl_init, | ||
323 | .map_io = orion5x_map_io, | ||
324 | .init_irq = orion5x_init_irq, | ||
325 | .timer = &orion5x_timer, | ||
326 | .fixup = tag_fixup_mem32, | ||
327 | MACHINE_END | ||
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index dd235ecc9d6c..1df6db6a136e 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -50,6 +50,10 @@ config MACH_SAAR | |||
50 | select PXA3xx | 50 | select PXA3xx |
51 | select CPU_PXA930 | 51 | select CPU_PXA930 |
52 | 52 | ||
53 | config MACH_SAARB | ||
54 | bool "PXA955 Handheld Platform (aka SAARB)" | ||
55 | select CPU_PXA955 | ||
56 | |||
53 | comment "Third Party Dev Platforms (sorted by vendor name)" | 57 | comment "Third Party Dev Platforms (sorted by vendor name)" |
54 | 58 | ||
55 | config ARCH_PXA_IDP | 59 | config ARCH_PXA_IDP |
@@ -232,10 +236,6 @@ config MACH_COLIBRI | |||
232 | bool "Toradex Colibri PXA270" | 236 | bool "Toradex Colibri PXA270" |
233 | select PXA27x | 237 | select PXA27x |
234 | 238 | ||
235 | config MACH_COLIBRI_PXA270_EVALBOARD | ||
236 | bool "Toradex Colibri Evaluation Carrier Board support (PXA270)" | ||
237 | depends on MACH_COLIBRI | ||
238 | |||
239 | config MACH_COLIBRI_PXA270_INCOME | 239 | config MACH_COLIBRI_PXA270_INCOME |
240 | bool "Income s.r.o. PXA270 SBC" | 240 | bool "Income s.r.o. PXA270 SBC" |
241 | depends on MACH_COLIBRI | 241 | depends on MACH_COLIBRI |
@@ -253,6 +253,10 @@ config MACH_COLIBRI320 | |||
253 | select PXA3xx | 253 | select PXA3xx |
254 | select CPU_PXA320 | 254 | select CPU_PXA320 |
255 | 255 | ||
256 | config MACH_COLIBRI_EVALBOARD | ||
257 | bool "Toradex Colibri Evaluation Carrier Board support" | ||
258 | depends on MACH_COLIBRI || MACH_COLIBRI300 || MACH_COLIBRI320 | ||
259 | |||
256 | config MACH_VPAC270 | 260 | config MACH_VPAC270 |
257 | bool "Voipac PXA270" | 261 | bool "Voipac PXA270" |
258 | select PXA27x | 262 | select PXA27x |
@@ -651,11 +655,17 @@ config CPU_PXA935 | |||
651 | help | 655 | help |
652 | PXA935 (codename Tavor-P65) | 656 | PXA935 (codename Tavor-P65) |
653 | 657 | ||
654 | config CPU_PXA950 | 658 | config PXA95x |
655 | bool | 659 | bool |
656 | select CPU_PXA930 | 660 | select CPU_PJ4 |
661 | help | ||
662 | Select code specific to PXA95x variants | ||
663 | |||
664 | config CPU_PXA955 | ||
665 | bool | ||
666 | select PXA95x | ||
657 | help | 667 | help |
658 | PXA950 (codename Tavor-PV2) | 668 | PXA950 (codename MG1) |
659 | 669 | ||
660 | config PXA_SHARP_C7xx | 670 | config PXA_SHARP_C7xx |
661 | bool | 671 | bool |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index e2f89c2c6f49..cc39d17b2e07 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -16,9 +16,10 @@ endif | |||
16 | # Generic drivers that other drivers may depend upon | 16 | # Generic drivers that other drivers may depend upon |
17 | 17 | ||
18 | # SoC-specific code | 18 | # SoC-specific code |
19 | obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o | 19 | obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa25x.o |
20 | obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o | 20 | obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa27x.o |
21 | obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o | 21 | obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o clock-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o |
22 | obj-$(CONFIG_PXA95x) += mfp-pxa3xx.o clock-pxa3xx.o pxa95x.o smemc.o | ||
22 | obj-$(CONFIG_CPU_PXA300) += pxa300.o | 23 | obj-$(CONFIG_CPU_PXA300) += pxa300.o |
23 | obj-$(CONFIG_CPU_PXA320) += pxa320.o | 24 | obj-$(CONFIG_CPU_PXA320) += pxa320.o |
24 | obj-$(CONFIG_CPU_PXA930) += pxa930.o | 25 | obj-$(CONFIG_CPU_PXA930) += pxa930.o |
@@ -34,6 +35,7 @@ obj-$(CONFIG_MACH_LITTLETON) += littleton.o | |||
34 | obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o | 35 | obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o |
35 | obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o | 36 | obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o |
36 | obj-$(CONFIG_MACH_SAAR) += saar.o | 37 | obj-$(CONFIG_MACH_SAAR) += saar.o |
38 | obj-$(CONFIG_MACH_SAARB) += saarb.o | ||
37 | 39 | ||
38 | # 3rd Party Dev Platforms | 40 | # 3rd Party Dev Platforms |
39 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o | 41 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o |
@@ -60,7 +62,7 @@ obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o | |||
60 | obj-$(CONFIG_MACH_PCM027) += pcm027.o | 62 | obj-$(CONFIG_MACH_PCM027) += pcm027.o |
61 | obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o | 63 | obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o |
62 | obj-$(CONFIG_MACH_COLIBRI) += colibri-pxa270.o | 64 | obj-$(CONFIG_MACH_COLIBRI) += colibri-pxa270.o |
63 | obj-$(CONFIG_MACH_COLIBRI_PXA270_EVALBOARD) += colibri-pxa270-evalboard.o | 65 | obj-$(CONFIG_MACH_COLIBRI_EVALBOARD) += colibri-evalboard.o |
64 | obj-$(CONFIG_MACH_COLIBRI_PXA270_INCOME) += colibri-pxa270-income.o | 66 | obj-$(CONFIG_MACH_COLIBRI_PXA270_INCOME) += colibri-pxa270-income.o |
65 | obj-$(CONFIG_MACH_COLIBRI300) += colibri-pxa3xx.o colibri-pxa300.o | 67 | obj-$(CONFIG_MACH_COLIBRI300) += colibri-pxa3xx.o colibri-pxa300.o |
66 | obj-$(CONFIG_MACH_COLIBRI320) += colibri-pxa3xx.o colibri-pxa320.o | 68 | obj-$(CONFIG_MACH_COLIBRI320) += colibri-pxa3xx.o colibri-pxa320.o |
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 21e188901935..ccb2d0cebcc3 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c | |||
@@ -567,27 +567,29 @@ static inline void balloon3_i2c_init(void) {} | |||
567 | * NAND | 567 | * NAND |
568 | ******************************************************************************/ | 568 | ******************************************************************************/ |
569 | #if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | 569 | #if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) |
570 | static uint16_t balloon3_ctl = | ||
571 | BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 | | ||
572 | BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 | | ||
573 | BALLOON3_NAND_CONTROL_FLWP; | ||
574 | |||
575 | static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 570 | static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
576 | { | 571 | { |
577 | struct nand_chip *this = mtd->priv; | 572 | struct nand_chip *this = mtd->priv; |
573 | uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0; | ||
578 | 574 | ||
579 | if (ctrl & NAND_CTRL_CHANGE) { | 575 | if (ctrl & NAND_CTRL_CHANGE) { |
580 | if (ctrl & NAND_CLE) | 576 | if (ctrl & NAND_CLE) |
581 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCLE; | 577 | balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLCLE; |
582 | else | 578 | else |
583 | balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLCLE; | 579 | balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLCLE; |
584 | 580 | ||
585 | if (ctrl & NAND_ALE) | 581 | if (ctrl & NAND_ALE) |
586 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLALE; | 582 | balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLALE; |
587 | else | 583 | else |
588 | balloon3_ctl &= ~BALLOON3_NAND_CONTROL_FLALE; | 584 | balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLALE; |
589 | 585 | ||
590 | __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | 586 | if (balloon3_ctl_clr) |
587 | __raw_writel(balloon3_ctl_clr, | ||
588 | BALLOON3_NAND_CONTROL_REG); | ||
589 | if (balloon3_ctl_set) | ||
590 | __raw_writel(balloon3_ctl_set, | ||
591 | BALLOON3_NAND_CONTROL_REG | | ||
592 | BALLOON3_FPGA_SETnCLR); | ||
591 | } | 593 | } |
592 | 594 | ||
593 | if (cmd != NAND_CMD_NONE) | 595 | if (cmd != NAND_CMD_NONE) |
@@ -599,28 +601,33 @@ static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip) | |||
599 | if (chip < 0 || chip > 3) | 601 | if (chip < 0 || chip > 3) |
600 | return; | 602 | return; |
601 | 603 | ||
602 | balloon3_ctl |= BALLOON3_NAND_CONTROL_FLCE0 | | 604 | /* Assert all nCE lines */ |
603 | BALLOON3_NAND_CONTROL_FLCE1 | | 605 | __raw_writew( |
604 | BALLOON3_NAND_CONTROL_FLCE2 | | 606 | BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 | |
605 | BALLOON3_NAND_CONTROL_FLCE3; | 607 | BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3, |
608 | BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR); | ||
606 | 609 | ||
607 | /* Deassert correct nCE line */ | 610 | /* Deassert correct nCE line */ |
608 | balloon3_ctl &= ~(BALLOON3_NAND_CONTROL_FLCE0 << chip); | 611 | __raw_writew(BALLOON3_NAND_CONTROL_FLCE0 << chip, |
612 | BALLOON3_NAND_CONTROL_REG); | ||
613 | } | ||
609 | 614 | ||
610 | __raw_writew(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | 615 | static int balloon3_nand_dev_ready(struct mtd_info *mtd) |
616 | { | ||
617 | return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB; | ||
611 | } | 618 | } |
612 | 619 | ||
613 | static int balloon3_nand_probe(struct platform_device *pdev) | 620 | static int balloon3_nand_probe(struct platform_device *pdev) |
614 | { | 621 | { |
615 | void __iomem *temp_map; | ||
616 | uint16_t ver; | 622 | uint16_t ver; |
617 | int ret; | 623 | int ret; |
618 | 624 | ||
619 | __raw_writew(BALLOON3_NAND_CONTROL2_16BIT, BALLOON3_NAND_CONTROL2_REG); | 625 | __raw_writew(BALLOON3_NAND_CONTROL2_16BIT, |
626 | BALLOON3_NAND_CONTROL2_REG | BALLOON3_FPGA_SETnCLR); | ||
620 | 627 | ||
621 | ver = __raw_readw(BALLOON3_FPGA_VER); | 628 | ver = __raw_readw(BALLOON3_FPGA_VER); |
622 | if (ver > 0x0201) | 629 | if (ver < 0x4f08) |
623 | pr_warn("The FPGA code, version 0x%04x, is newer than rel-0.3. " | 630 | pr_warn("The FPGA code, version 0x%04x, is too old. " |
624 | "NAND support might be broken in this version!", ver); | 631 | "NAND support might be broken in this version!", ver); |
625 | 632 | ||
626 | /* Power up the NAND chips */ | 633 | /* Power up the NAND chips */ |
@@ -635,7 +642,11 @@ static int balloon3_nand_probe(struct platform_device *pdev) | |||
635 | gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1); | 642 | gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1); |
636 | 643 | ||
637 | /* Deassert all nCE lines and write protect line */ | 644 | /* Deassert all nCE lines and write protect line */ |
638 | __raw_writel(balloon3_ctl, BALLOON3_NAND_CONTROL_REG); | 645 | __raw_writel( |
646 | BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 | | ||
647 | BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 | | ||
648 | BALLOON3_NAND_CONTROL_FLWP, | ||
649 | BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR); | ||
639 | return 0; | 650 | return 0; |
640 | 651 | ||
641 | err2: | 652 | err2: |
@@ -677,7 +688,7 @@ struct platform_nand_data balloon3_nand_pdata = { | |||
677 | }, | 688 | }, |
678 | .ctrl = { | 689 | .ctrl = { |
679 | .hwcontrol = 0, | 690 | .hwcontrol = 0, |
680 | .dev_ready = 0, | 691 | .dev_ready = balloon3_nand_dev_ready, |
681 | .select_chip = balloon3_nand_select_chip, | 692 | .select_chip = balloon3_nand_select_chip, |
682 | .cmd_ctrl = balloon3_nand_cmd_ctl, | 693 | .cmd_ctrl = balloon3_nand_cmd_ctl, |
683 | .probe = balloon3_nand_probe, | 694 | .probe = balloon3_nand_probe, |
@@ -802,7 +813,7 @@ static struct map_desc balloon3_io_desc[] __initdata = { | |||
802 | 813 | ||
803 | static void __init balloon3_map_io(void) | 814 | static void __init balloon3_map_io(void) |
804 | { | 815 | { |
805 | pxa_map_io(); | 816 | pxa27x_map_io(); |
806 | iotable_init(balloon3_io_desc, ARRAY_SIZE(balloon3_io_desc)); | 817 | iotable_init(balloon3_io_desc, ARRAY_SIZE(balloon3_io_desc)); |
807 | } | 818 | } |
808 | 819 | ||
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c index 4bd7a3cda48c..4284513f396a 100644 --- a/arch/arm/mach-pxa/capc7117.c +++ b/arch/arm/mach-pxa/capc7117.c | |||
@@ -149,7 +149,7 @@ static void __init capc7117_init(void) | |||
149 | MACHINE_START(CAPC7117, | 149 | MACHINE_START(CAPC7117, |
150 | "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM") | 150 | "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM") |
151 | .boot_params = 0xa0000100, | 151 | .boot_params = 0xa0000100, |
152 | .map_io = pxa_map_io, | 152 | .map_io = pxa3xx_map_io, |
153 | .init_irq = pxa3xx_init_irq, | 153 | .init_irq = pxa3xx_init_irq, |
154 | .timer = &pxa_timer, | 154 | .timer = &pxa_timer, |
155 | .init_machine = capc7117_init | 155 | .init_machine = capc7117_init |
diff --git a/arch/arm/mach-pxa/clock-pxa2xx.c b/arch/arm/mach-pxa/clock-pxa2xx.c new file mode 100644 index 000000000000..1ce090448493 --- /dev/null +++ b/arch/arm/mach-pxa/clock-pxa2xx.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/clock-pxa2xx.c | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/sysdev.h> | ||
13 | |||
14 | #include <mach/pxa2xx-regs.h> | ||
15 | |||
16 | #include "clock.h" | ||
17 | |||
18 | void clk_pxa2xx_cken_enable(struct clk *clk) | ||
19 | { | ||
20 | CKEN |= 1 << clk->cken; | ||
21 | } | ||
22 | |||
23 | void clk_pxa2xx_cken_disable(struct clk *clk) | ||
24 | { | ||
25 | CKEN &= ~(1 << clk->cken); | ||
26 | } | ||
27 | |||
28 | const struct clkops clk_pxa2xx_cken_ops = { | ||
29 | .enable = clk_pxa2xx_cken_enable, | ||
30 | .disable = clk_pxa2xx_cken_disable, | ||
31 | }; | ||
32 | |||
33 | #ifdef CONFIG_PM | ||
34 | static uint32_t saved_cken; | ||
35 | |||
36 | static int pxa2xx_clock_suspend(struct sys_device *d, pm_message_t state) | ||
37 | { | ||
38 | saved_cken = CKEN; | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static int pxa2xx_clock_resume(struct sys_device *d) | ||
43 | { | ||
44 | CKEN = saved_cken; | ||
45 | return 0; | ||
46 | } | ||
47 | #else | ||
48 | #define pxa2xx_clock_suspend NULL | ||
49 | #define pxa2xx_clock_resume NULL | ||
50 | #endif | ||
51 | |||
52 | struct sysdev_class pxa2xx_clock_sysclass = { | ||
53 | .name = "pxa2xx-clock", | ||
54 | .suspend = pxa2xx_clock_suspend, | ||
55 | .resume = pxa2xx_clock_resume, | ||
56 | }; | ||
57 | |||
58 | static int __init pxa2xx_clock_init(void) | ||
59 | { | ||
60 | if (cpu_is_pxa2xx()) | ||
61 | return sysdev_class_register(&pxa2xx_clock_sysclass); | ||
62 | return 0; | ||
63 | } | ||
64 | postcore_initcall(pxa2xx_clock_init); | ||
diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c new file mode 100644 index 000000000000..1b08a34ab234 --- /dev/null +++ b/arch/arm/mach-pxa/clock-pxa3xx.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/clock-pxa3xx.c | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/io.h> | ||
13 | |||
14 | #include <mach/smemc.h> | ||
15 | #include <mach/pxa3xx-regs.h> | ||
16 | |||
17 | #include "clock.h" | ||
18 | |||
19 | /* Crystal clock: 13MHz */ | ||
20 | #define BASE_CLK 13000000 | ||
21 | |||
22 | /* Ring Oscillator Clock: 60MHz */ | ||
23 | #define RO_CLK 60000000 | ||
24 | |||
25 | #define ACCR_D0CS (1 << 26) | ||
26 | #define ACCR_PCCE (1 << 11) | ||
27 | |||
28 | /* crystal frequency to HSIO bus frequency multiplier (HSS) */ | ||
29 | static unsigned char hss_mult[4] = { 8, 12, 16, 24 }; | ||
30 | |||
31 | /* | ||
32 | * Get the clock frequency as reflected by CCSR and the turbo flag. | ||
33 | * We assume these values have been applied via a fcs. | ||
34 | * If info is not 0 we also display the current settings. | ||
35 | */ | ||
36 | unsigned int pxa3xx_get_clk_frequency_khz(int info) | ||
37 | { | ||
38 | unsigned long acsr, xclkcfg; | ||
39 | unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS; | ||
40 | |||
41 | /* Read XCLKCFG register turbo bit */ | ||
42 | __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg)); | ||
43 | t = xclkcfg & 0x1; | ||
44 | |||
45 | acsr = ACSR; | ||
46 | |||
47 | xl = acsr & 0x1f; | ||
48 | xn = (acsr >> 8) & 0x7; | ||
49 | hss = (acsr >> 14) & 0x3; | ||
50 | |||
51 | XL = xl * BASE_CLK; | ||
52 | XN = xn * XL; | ||
53 | |||
54 | ro = acsr & ACCR_D0CS; | ||
55 | |||
56 | CLK = (ro) ? RO_CLK : ((t) ? XN : XL); | ||
57 | HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK; | ||
58 | |||
59 | if (info) { | ||
60 | pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n", | ||
61 | RO_CLK / 1000000, (RO_CLK % 1000000) / 10000, | ||
62 | (ro) ? "" : "in"); | ||
63 | pr_info("Run Mode clock: %d.%02dMHz (*%d)\n", | ||
64 | XL / 1000000, (XL % 1000000) / 10000, xl); | ||
65 | pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n", | ||
66 | XN / 1000000, (XN % 1000000) / 10000, xn, | ||
67 | (t) ? "" : "in"); | ||
68 | pr_info("HSIO bus clock: %d.%02dMHz\n", | ||
69 | HSS / 1000000, (HSS % 1000000) / 10000); | ||
70 | } | ||
71 | |||
72 | return CLK / 1000; | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * Return the current AC97 clock frequency. | ||
77 | */ | ||
78 | static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk) | ||
79 | { | ||
80 | unsigned long rate = 312000000; | ||
81 | unsigned long ac97_div; | ||
82 | |||
83 | ac97_div = AC97_DIV; | ||
84 | |||
85 | /* This may loose precision for some rates but won't for the | ||
86 | * standard 24.576MHz. | ||
87 | */ | ||
88 | rate /= (ac97_div >> 12) & 0x7fff; | ||
89 | rate *= (ac97_div & 0xfff); | ||
90 | |||
91 | return rate; | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Return the current HSIO bus clock frequency | ||
96 | */ | ||
97 | static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) | ||
98 | { | ||
99 | unsigned long acsr; | ||
100 | unsigned int hss, hsio_clk; | ||
101 | |||
102 | acsr = ACSR; | ||
103 | |||
104 | hss = (acsr >> 14) & 0x3; | ||
105 | hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK; | ||
106 | |||
107 | return hsio_clk; | ||
108 | } | ||
109 | |||
110 | /* crystal frequency to static memory controller multiplier (SMCFS) */ | ||
111 | static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; | ||
112 | static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 }; | ||
113 | |||
114 | static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk) | ||
115 | { | ||
116 | unsigned long acsr = ACSR; | ||
117 | unsigned long memclkcfg = __raw_readl(MEMCLKCFG); | ||
118 | unsigned int smcfs = (acsr >> 23) & 0x7; | ||
119 | |||
120 | return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] / | ||
121 | df_clkdiv[(memclkcfg >> 16) & 0x3]; | ||
122 | } | ||
123 | |||
124 | void clk_pxa3xx_cken_enable(struct clk *clk) | ||
125 | { | ||
126 | unsigned long mask = 1ul << (clk->cken & 0x1f); | ||
127 | |||
128 | if (clk->cken < 32) | ||
129 | CKENA |= mask; | ||
130 | else | ||
131 | CKENB |= mask; | ||
132 | } | ||
133 | |||
134 | void clk_pxa3xx_cken_disable(struct clk *clk) | ||
135 | { | ||
136 | unsigned long mask = 1ul << (clk->cken & 0x1f); | ||
137 | |||
138 | if (clk->cken < 32) | ||
139 | CKENA &= ~mask; | ||
140 | else | ||
141 | CKENB &= ~mask; | ||
142 | } | ||
143 | |||
144 | const struct clkops clk_pxa3xx_cken_ops = { | ||
145 | .enable = clk_pxa3xx_cken_enable, | ||
146 | .disable = clk_pxa3xx_cken_disable, | ||
147 | }; | ||
148 | |||
149 | const struct clkops clk_pxa3xx_hsio_ops = { | ||
150 | .enable = clk_pxa3xx_cken_enable, | ||
151 | .disable = clk_pxa3xx_cken_disable, | ||
152 | .getrate = clk_pxa3xx_hsio_getrate, | ||
153 | }; | ||
154 | |||
155 | const struct clkops clk_pxa3xx_ac97_ops = { | ||
156 | .enable = clk_pxa3xx_cken_enable, | ||
157 | .disable = clk_pxa3xx_cken_disable, | ||
158 | .getrate = clk_pxa3xx_ac97_getrate, | ||
159 | }; | ||
160 | |||
161 | const struct clkops clk_pxa3xx_smemc_ops = { | ||
162 | .enable = clk_pxa3xx_cken_enable, | ||
163 | .disable = clk_pxa3xx_cken_disable, | ||
164 | .getrate = clk_pxa3xx_smemc_getrate, | ||
165 | }; | ||
166 | |||
167 | static void clk_pout_enable(struct clk *clk) | ||
168 | { | ||
169 | OSCC |= OSCC_PEN; | ||
170 | } | ||
171 | |||
172 | static void clk_pout_disable(struct clk *clk) | ||
173 | { | ||
174 | OSCC &= ~OSCC_PEN; | ||
175 | } | ||
176 | |||
177 | const struct clkops clk_pxa3xx_pout_ops = { | ||
178 | .enable = clk_pout_enable, | ||
179 | .disable = clk_pout_disable, | ||
180 | }; | ||
181 | |||
182 | #ifdef CONFIG_PM | ||
183 | static uint32_t cken[2]; | ||
184 | static uint32_t accr; | ||
185 | |||
186 | static int pxa3xx_clock_suspend(struct sys_device *d, pm_message_t state) | ||
187 | { | ||
188 | cken[0] = CKENA; | ||
189 | cken[1] = CKENB; | ||
190 | accr = ACCR; | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static int pxa3xx_clock_resume(struct sys_device *d) | ||
195 | { | ||
196 | ACCR = accr; | ||
197 | CKENA = cken[0]; | ||
198 | CKENB = cken[1]; | ||
199 | return 0; | ||
200 | } | ||
201 | #else | ||
202 | #define pxa3xx_clock_suspend NULL | ||
203 | #define pxa3xx_clock_resume NULL | ||
204 | #endif | ||
205 | |||
206 | struct sysdev_class pxa3xx_clock_sysclass = { | ||
207 | .name = "pxa3xx-clock", | ||
208 | .suspend = pxa3xx_clock_suspend, | ||
209 | .resume = pxa3xx_clock_resume, | ||
210 | }; | ||
211 | |||
212 | static int __init pxa3xx_clock_init(void) | ||
213 | { | ||
214 | if (cpu_is_pxa3xx() || cpu_is_pxa95x()) | ||
215 | return sysdev_class_register(&pxa3xx_clock_sysclass); | ||
216 | return 0; | ||
217 | } | ||
218 | postcore_initcall(pxa3xx_clock_init); | ||
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index abba0089a2ae..8184fe2d71c3 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c | |||
@@ -3,21 +3,12 @@ | |||
3 | */ | 3 | */ |
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/list.h> | ||
7 | #include <linux/errno.h> | ||
8 | #include <linux/err.h> | ||
9 | #include <linux/string.h> | ||
10 | #include <linux/clk.h> | 6 | #include <linux/clk.h> |
11 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
14 | 9 | ||
15 | #include <asm/clkdev.h> | 10 | #include <asm/clkdev.h> |
16 | #include <mach/pxa2xx-regs.h> | ||
17 | #include <mach/hardware.h> | ||
18 | 11 | ||
19 | #include "devices.h" | ||
20 | #include "generic.h" | ||
21 | #include "clock.h" | 12 | #include "clock.h" |
22 | 13 | ||
23 | static DEFINE_SPINLOCK(clocks_lock); | 14 | static DEFINE_SPINLOCK(clocks_lock); |
@@ -63,18 +54,19 @@ unsigned long clk_get_rate(struct clk *clk) | |||
63 | } | 54 | } |
64 | EXPORT_SYMBOL(clk_get_rate); | 55 | EXPORT_SYMBOL(clk_get_rate); |
65 | 56 | ||
66 | 57 | void clk_dummy_enable(struct clk *clk) | |
67 | void clk_cken_enable(struct clk *clk) | ||
68 | { | 58 | { |
69 | CKEN |= 1 << clk->cken; | ||
70 | } | 59 | } |
71 | 60 | ||
72 | void clk_cken_disable(struct clk *clk) | 61 | void clk_dummy_disable(struct clk *clk) |
73 | { | 62 | { |
74 | CKEN &= ~(1 << clk->cken); | ||
75 | } | 63 | } |
76 | 64 | ||
77 | const struct clkops clk_cken_ops = { | 65 | const struct clkops clk_dummy_ops = { |
78 | .enable = clk_cken_enable, | 66 | .enable = clk_dummy_enable, |
79 | .disable = clk_cken_disable, | 67 | .disable = clk_dummy_disable, |
68 | }; | ||
69 | |||
70 | struct clk clk_dummy = { | ||
71 | .ops = &clk_dummy_ops, | ||
80 | }; | 72 | }; |
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h index d8488742b807..6e949944f2ec 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/sysdev.h> | ||
1 | #include <asm/clkdev.h> | 2 | #include <asm/clkdev.h> |
2 | 3 | ||
3 | struct clkops { | 4 | struct clkops { |
@@ -14,6 +15,12 @@ struct clk { | |||
14 | unsigned int enabled; | 15 | unsigned int enabled; |
15 | }; | 16 | }; |
16 | 17 | ||
18 | void clk_dummy_enable(struct clk *); | ||
19 | void clk_dummy_disable(struct clk *); | ||
20 | |||
21 | extern const struct clkops clk_dummy_ops; | ||
22 | extern struct clk clk_dummy; | ||
23 | |||
17 | #define INIT_CLKREG(_clk,_devname,_conname) \ | 24 | #define INIT_CLKREG(_clk,_devname,_conname) \ |
18 | { \ | 25 | { \ |
19 | .clk = _clk, \ | 26 | .clk = _clk, \ |
@@ -21,14 +28,6 @@ struct clk { | |||
21 | .con_id = _conname, \ | 28 | .con_id = _conname, \ |
22 | } | 29 | } |
23 | 30 | ||
24 | #define DEFINE_CKEN(_name, _cken, _rate, _delay) \ | ||
25 | struct clk clk_##_name = { \ | ||
26 | .ops = &clk_cken_ops, \ | ||
27 | .rate = _rate, \ | ||
28 | .cken = CKEN_##_cken, \ | ||
29 | .delay = _delay, \ | ||
30 | } | ||
31 | |||
32 | #define DEFINE_CK(_name, _cken, _ops) \ | 31 | #define DEFINE_CK(_name, _cken, _ops) \ |
33 | struct clk clk_##_name = { \ | 32 | struct clk clk_##_name = { \ |
34 | .ops = _ops, \ | 33 | .ops = _ops, \ |
@@ -42,28 +41,38 @@ struct clk clk_##_name = { \ | |||
42 | .delay = _delay, \ | 41 | .delay = _delay, \ |
43 | } | 42 | } |
44 | 43 | ||
45 | extern const struct clkops clk_cken_ops; | 44 | #define DEFINE_PXA2_CKEN(_name, _cken, _rate, _delay) \ |
46 | |||
47 | void clk_cken_enable(struct clk *clk); | ||
48 | void clk_cken_disable(struct clk *clk); | ||
49 | |||
50 | #ifdef CONFIG_PXA3xx | ||
51 | #define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \ | ||
52 | struct clk clk_##_name = { \ | 45 | struct clk clk_##_name = { \ |
53 | .ops = &clk_pxa3xx_cken_ops, \ | 46 | .ops = &clk_pxa2xx_cken_ops, \ |
54 | .rate = _rate, \ | 47 | .rate = _rate, \ |
55 | .cken = CKEN_##_cken, \ | 48 | .cken = CKEN_##_cken, \ |
56 | .delay = _delay, \ | 49 | .delay = _delay, \ |
57 | } | 50 | } |
58 | 51 | ||
59 | #define DEFINE_PXA3_CK(_name, _cken, _ops) \ | 52 | extern const struct clkops clk_pxa2xx_cken_ops; |
53 | |||
54 | void clk_pxa2xx_cken_enable(struct clk *clk); | ||
55 | void clk_pxa2xx_cken_disable(struct clk *clk); | ||
56 | |||
57 | extern struct sysdev_class pxa2xx_clock_sysclass; | ||
58 | |||
59 | #if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) | ||
60 | #define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \ | ||
60 | struct clk clk_##_name = { \ | 61 | struct clk clk_##_name = { \ |
61 | .ops = _ops, \ | 62 | .ops = &clk_pxa3xx_cken_ops, \ |
63 | .rate = _rate, \ | ||
62 | .cken = CKEN_##_cken, \ | 64 | .cken = CKEN_##_cken, \ |
65 | .delay = _delay, \ | ||
63 | } | 66 | } |
64 | 67 | ||
65 | extern const struct clkops clk_pxa3xx_cken_ops; | 68 | extern const struct clkops clk_pxa3xx_cken_ops; |
69 | extern const struct clkops clk_pxa3xx_hsio_ops; | ||
70 | extern const struct clkops clk_pxa3xx_ac97_ops; | ||
71 | extern const struct clkops clk_pxa3xx_pout_ops; | ||
72 | extern const struct clkops clk_pxa3xx_smemc_ops; | ||
73 | |||
66 | extern void clk_pxa3xx_cken_enable(struct clk *); | 74 | extern void clk_pxa3xx_cken_enable(struct clk *); |
67 | extern void clk_pxa3xx_cken_disable(struct clk *); | 75 | extern void clk_pxa3xx_cken_disable(struct clk *); |
68 | #endif | ||
69 | 76 | ||
77 | extern struct sysdev_class pxa3xx_clock_sysclass; | ||
78 | #endif | ||
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index d34b99febeb9..b734d8468168 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <mach/pxa2xx-regs.h> | 24 | #include <mach/pxa2xx-regs.h> |
25 | #include <mach/audio.h> | 25 | #include <mach/audio.h> |
26 | #include <mach/pxafb.h> | 26 | #include <mach/pxafb.h> |
27 | #include <mach/smemc.h> | ||
27 | 28 | ||
28 | #include <asm/hardware/it8152.h> | 29 | #include <asm/hardware/it8152.h> |
29 | 30 | ||
@@ -392,9 +393,9 @@ static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state) | |||
392 | cmx2xx_pci_suspend(); | 393 | cmx2xx_pci_suspend(); |
393 | 394 | ||
394 | /* save MSC registers */ | 395 | /* save MSC registers */ |
395 | sleep_save_msc[0] = MSC0; | 396 | sleep_save_msc[0] = __raw_readl(MSC0); |
396 | sleep_save_msc[1] = MSC1; | 397 | sleep_save_msc[1] = __raw_readl(MSC1); |
397 | sleep_save_msc[2] = MSC2; | 398 | sleep_save_msc[2] = __raw_readl(MSC2); |
398 | 399 | ||
399 | /* setup power saving mode registers */ | 400 | /* setup power saving mode registers */ |
400 | PCFR = 0x0; | 401 | PCFR = 0x0; |
@@ -416,9 +417,9 @@ static int cmx2xx_resume(struct sys_device *dev) | |||
416 | cmx2xx_pci_resume(); | 417 | cmx2xx_pci_resume(); |
417 | 418 | ||
418 | /* restore MSC registers */ | 419 | /* restore MSC registers */ |
419 | MSC0 = sleep_save_msc[0]; | 420 | __raw_writel(sleep_save_msc[0], MSC0); |
420 | MSC1 = sleep_save_msc[1]; | 421 | __raw_writel(sleep_save_msc[1], MSC1); |
421 | MSC2 = sleep_save_msc[2]; | 422 | __raw_writel(sleep_save_msc[2], MSC2); |
422 | 423 | ||
423 | return 0; | 424 | return 0; |
424 | } | 425 | } |
@@ -498,7 +499,12 @@ static struct map_desc cmx2xx_io_desc[] __initdata = { | |||
498 | 499 | ||
499 | static void __init cmx2xx_map_io(void) | 500 | static void __init cmx2xx_map_io(void) |
500 | { | 501 | { |
501 | pxa_map_io(); | 502 | if (cpu_is_pxa25x()) |
503 | pxa25x_map_io(); | ||
504 | |||
505 | if (cpu_is_pxa27x()) | ||
506 | pxa27x_map_io(); | ||
507 | |||
502 | iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc)); | 508 | iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc)); |
503 | 509 | ||
504 | it8152_base_address = CMX2XX_IT8152_VIRT; | 510 | it8152_base_address = CMX2XX_IT8152_VIRT; |
@@ -506,7 +512,11 @@ static void __init cmx2xx_map_io(void) | |||
506 | #else | 512 | #else |
507 | static void __init cmx2xx_map_io(void) | 513 | static void __init cmx2xx_map_io(void) |
508 | { | 514 | { |
509 | pxa_map_io(); | 515 | if (cpu_is_pxa25x()) |
516 | pxa25x_map_io(); | ||
517 | |||
518 | if (cpu_is_pxa27x()) | ||
519 | pxa27x_map_io(); | ||
510 | } | 520 | } |
511 | #endif | 521 | #endif |
512 | 522 | ||
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 922b1075b9de..7984268508b6 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c | |||
@@ -857,7 +857,7 @@ static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags, | |||
857 | 857 | ||
858 | MACHINE_START(CM_X300, "CM-X300 module") | 858 | MACHINE_START(CM_X300, "CM-X300 module") |
859 | .boot_params = 0xa0000100, | 859 | .boot_params = 0xa0000100, |
860 | .map_io = pxa_map_io, | 860 | .map_io = pxa3xx_map_io, |
861 | .init_irq = pxa3xx_init_irq, | 861 | .init_irq = pxa3xx_init_irq, |
862 | .timer = &pxa_timer, | 862 | .timer = &pxa_timer, |
863 | .init_machine = cm_x300_init, | 863 | .init_machine = cm_x300_init, |
diff --git a/arch/arm/mach-pxa/colibri-pxa270-evalboard.c b/arch/arm/mach-pxa/colibri-evalboard.c index 0f3b632c3b14..6b2c800a1133 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-evalboard.c +++ b/arch/arm/mach-pxa/colibri-evalboard.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-pxa/colibri-pxa270-evalboard.c | 2 | * linux/arch/arm/mach-pxa/colibri-evalboard.c |
3 | * | 3 | * |
4 | * Support for Toradex PXA270 based Colibri Evaluation Carrier Board | 4 | * Support for Toradex Colibri Evaluation Carrier Board |
5 | * Daniel Mack <daniel@caiaq.de> | 5 | * Daniel Mack <daniel@caiaq.de> |
6 | * Marek Vasut <marek.vasut@gmail.com> | 6 | * Marek Vasut <marek.vasut@gmail.com> |
7 | * | 7 | * |
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/mach-types.h> | 19 | #include <asm/mach-types.h> |
20 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
21 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
22 | #include <linux/i2c.h> | ||
22 | 23 | ||
23 | #include <mach/pxa27x.h> | 24 | #include <mach/pxa27x.h> |
24 | #include <mach/colibri.h> | 25 | #include <mach/colibri.h> |
@@ -26,86 +27,95 @@ | |||
26 | #include <mach/ohci.h> | 27 | #include <mach/ohci.h> |
27 | #include <mach/pxa27x-udc.h> | 28 | #include <mach/pxa27x-udc.h> |
28 | 29 | ||
30 | #include <plat/i2c.h> | ||
31 | |||
29 | #include "generic.h" | 32 | #include "generic.h" |
30 | #include "devices.h" | 33 | #include "devices.h" |
31 | 34 | ||
32 | /****************************************************************************** | 35 | /****************************************************************************** |
33 | * Pin configuration | ||
34 | ******************************************************************************/ | ||
35 | static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = { | ||
36 | /* MMC */ | ||
37 | GPIO32_MMC_CLK, | ||
38 | GPIO92_MMC_DAT_0, | ||
39 | GPIO109_MMC_DAT_1, | ||
40 | GPIO110_MMC_DAT_2, | ||
41 | GPIO111_MMC_DAT_3, | ||
42 | GPIO112_MMC_CMD, | ||
43 | GPIO0_GPIO, /* SD detect */ | ||
44 | |||
45 | /* FFUART */ | ||
46 | GPIO39_FFUART_TXD, | ||
47 | GPIO34_FFUART_RXD, | ||
48 | |||
49 | /* UHC */ | ||
50 | GPIO88_USBH1_PWR, | ||
51 | GPIO89_USBH1_PEN, | ||
52 | GPIO119_USBH2_PWR, | ||
53 | GPIO120_USBH2_PEN, | ||
54 | }; | ||
55 | |||
56 | /****************************************************************************** | ||
57 | * SD/MMC card controller | 36 | * SD/MMC card controller |
58 | ******************************************************************************/ | 37 | ******************************************************************************/ |
59 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) | 38 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) |
60 | static struct pxamci_platform_data colibri_pxa270_mci_platform_data = { | 39 | static struct pxamci_platform_data colibri_mci_platform_data = { |
61 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 40 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
62 | .gpio_power = -1, | 41 | .gpio_power = -1, |
63 | .gpio_card_detect = GPIO0_COLIBRI_PXA270_SD_DETECT, | ||
64 | .gpio_card_ro = -1, | 42 | .gpio_card_ro = -1, |
65 | .detect_delay_ms = 200, | 43 | .detect_delay_ms = 200, |
66 | }; | 44 | }; |
67 | 45 | ||
68 | static void __init colibri_pxa270_mmc_init(void) | 46 | static void __init colibri_mmc_init(void) |
69 | { | 47 | { |
70 | pxa_set_mci_info(&colibri_pxa270_mci_platform_data); | 48 | if (machine_is_colibri()) /* PXA270 Colibri */ |
49 | colibri_mci_platform_data.gpio_card_detect = | ||
50 | GPIO0_COLIBRI_PXA270_SD_DETECT; | ||
51 | if (machine_is_colibri300()) /* PXA300 Colibri */ | ||
52 | colibri_mci_platform_data.gpio_card_detect = | ||
53 | GPIO39_COLIBRI_PXA300_SD_DETECT; | ||
54 | else /* PXA320 Colibri */ | ||
55 | colibri_mci_platform_data.gpio_card_detect = | ||
56 | GPIO28_COLIBRI_PXA320_SD_DETECT; | ||
57 | |||
58 | pxa_set_mci_info(&colibri_mci_platform_data); | ||
71 | } | 59 | } |
72 | #else | 60 | #else |
73 | static inline void colibri_pxa270_mmc_init(void) {} | 61 | static inline void colibri_mmc_init(void) {} |
74 | #endif | 62 | #endif |
75 | 63 | ||
76 | /****************************************************************************** | 64 | /****************************************************************************** |
77 | * USB Host | 65 | * USB Host |
78 | ******************************************************************************/ | 66 | ******************************************************************************/ |
79 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 67 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
80 | static int colibri_pxa270_ohci_init(struct device *dev) | 68 | static int colibri_ohci_init(struct device *dev) |
81 | { | 69 | { |
82 | UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; | 70 | UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; |
83 | return 0; | 71 | return 0; |
84 | } | 72 | } |
85 | 73 | ||
86 | static struct pxaohci_platform_data colibri_pxa270_ohci_info = { | 74 | static struct pxaohci_platform_data colibri_ohci_info = { |
87 | .port_mode = PMM_PERPORT_MODE, | 75 | .port_mode = PMM_PERPORT_MODE, |
88 | .flags = ENABLE_PORT1 | ENABLE_PORT2 | | 76 | .flags = ENABLE_PORT1 | |
89 | POWER_CONTROL_LOW | POWER_SENSE_LOW, | 77 | POWER_CONTROL_LOW | POWER_SENSE_LOW, |
90 | .init = colibri_pxa270_ohci_init, | 78 | .init = colibri_ohci_init, |
91 | }; | 79 | }; |
92 | 80 | ||
93 | static void __init colibri_pxa270_uhc_init(void) | 81 | static void __init colibri_uhc_init(void) |
94 | { | 82 | { |
95 | pxa_set_ohci_info(&colibri_pxa270_ohci_info); | 83 | /* Colibri PXA270 has two usb ports, TBA for 320 */ |
84 | if (machine_is_colibri()) | ||
85 | colibri_ohci_info.flags |= ENABLE_PORT2; | ||
86 | |||
87 | pxa_set_ohci_info(&colibri_ohci_info); | ||
96 | } | 88 | } |
97 | #else | 89 | #else |
98 | static inline void colibri_pxa270_uhc_init(void) {} | 90 | static inline void colibri_uhc_init(void) {} |
99 | #endif | 91 | #endif |
100 | 92 | ||
101 | void __init colibri_pxa270_evalboard_init(void) | 93 | /****************************************************************************** |
94 | * I2C RTC | ||
95 | ******************************************************************************/ | ||
96 | #if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE) | ||
97 | static struct i2c_board_info __initdata colibri_i2c_devs[] = { | ||
98 | { | ||
99 | I2C_BOARD_INFO("m41t00", 0x68), | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static void __init colibri_rtc_init(void) | ||
104 | { | ||
105 | pxa_set_i2c_info(NULL); | ||
106 | i2c_register_board_info(0, ARRAY_AND_SIZE(colibri_i2c_devs)); | ||
107 | } | ||
108 | #else | ||
109 | static inline void colibri_rtc_init(void) {} | ||
110 | #endif | ||
111 | |||
112 | void __init colibri_evalboard_init(void) | ||
102 | { | 113 | { |
103 | pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_evalboard_pin_config)); | ||
104 | pxa_set_ffuart_info(NULL); | 114 | pxa_set_ffuart_info(NULL); |
105 | pxa_set_btuart_info(NULL); | 115 | pxa_set_btuart_info(NULL); |
106 | pxa_set_stuart_info(NULL); | 116 | pxa_set_stuart_info(NULL); |
107 | 117 | ||
108 | colibri_pxa270_mmc_init(); | 118 | colibri_mmc_init(); |
109 | colibri_pxa270_uhc_init(); | 119 | colibri_uhc_init(); |
120 | colibri_rtc_init(); | ||
110 | } | 121 | } |
111 | |||
diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c index 37f0f3ed7c61..07b62a096f17 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-income.c +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c | |||
@@ -46,52 +46,6 @@ | |||
46 | #define GPIO113_INCOME_TS_IRQ (113) | 46 | #define GPIO113_INCOME_TS_IRQ (113) |
47 | 47 | ||
48 | /****************************************************************************** | 48 | /****************************************************************************** |
49 | * Pin configuration | ||
50 | ******************************************************************************/ | ||
51 | static mfp_cfg_t income_pin_config[] __initdata = { | ||
52 | /* MMC */ | ||
53 | GPIO32_MMC_CLK, | ||
54 | GPIO92_MMC_DAT_0, | ||
55 | GPIO109_MMC_DAT_1, | ||
56 | GPIO110_MMC_DAT_2, | ||
57 | GPIO111_MMC_DAT_3, | ||
58 | GPIO112_MMC_CMD, | ||
59 | GPIO0_GPIO, /* SD detect */ | ||
60 | GPIO1_GPIO, /* SD read-only */ | ||
61 | |||
62 | /* FFUART */ | ||
63 | GPIO39_FFUART_TXD, | ||
64 | GPIO34_FFUART_RXD, | ||
65 | |||
66 | /* BFUART */ | ||
67 | GPIO42_BTUART_RXD, | ||
68 | GPIO43_BTUART_TXD, | ||
69 | GPIO45_BTUART_RTS, | ||
70 | |||
71 | /* STUART */ | ||
72 | GPIO46_STUART_RXD, | ||
73 | GPIO47_STUART_TXD, | ||
74 | |||
75 | /* UHC */ | ||
76 | GPIO88_USBH1_PWR, | ||
77 | GPIO89_USBH1_PEN, | ||
78 | |||
79 | /* LCD */ | ||
80 | GPIOxx_LCD_TFT_16BPP, | ||
81 | |||
82 | /* PWM */ | ||
83 | GPIO16_PWM0_OUT, | ||
84 | |||
85 | /* I2C */ | ||
86 | GPIO117_I2C_SCL, | ||
87 | GPIO118_I2C_SDA, | ||
88 | |||
89 | /* LED */ | ||
90 | GPIO54_GPIO, /* LED A */ | ||
91 | GPIO55_GPIO, /* LED B */ | ||
92 | }; | ||
93 | |||
94 | /****************************************************************************** | ||
95 | * SD/MMC card controller | 49 | * SD/MMC card controller |
96 | ******************************************************************************/ | 50 | ******************************************************************************/ |
97 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) | 51 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) |
@@ -257,7 +211,6 @@ static inline void income_pwm_init(void) {} | |||
257 | 211 | ||
258 | void __init colibri_pxa270_income_boardinit(void) | 212 | void __init colibri_pxa270_income_boardinit(void) |
259 | { | 213 | { |
260 | pxa2xx_mfp_config(ARRAY_AND_SIZE(income_pin_config)); | ||
261 | pxa_set_ffuart_info(NULL); | 214 | pxa_set_ffuart_info(NULL); |
262 | pxa_set_btuart_info(NULL); | 215 | pxa_set_btuart_info(NULL); |
263 | pxa_set_stuart_info(NULL); | 216 | pxa_set_stuart_info(NULL); |
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c index bc045100ec15..6fc5d328ba7f 100644 --- a/arch/arm/mach-pxa/colibri-pxa270.c +++ b/arch/arm/mach-pxa/colibri-pxa270.c | |||
@@ -33,6 +33,103 @@ | |||
33 | #include "generic.h" | 33 | #include "generic.h" |
34 | 34 | ||
35 | /****************************************************************************** | 35 | /****************************************************************************** |
36 | * Evaluation board MFP | ||
37 | ******************************************************************************/ | ||
38 | #ifdef CONFIG_MACH_COLIBRI_EVALBOARD | ||
39 | static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = { | ||
40 | /* MMC */ | ||
41 | GPIO32_MMC_CLK, | ||
42 | GPIO92_MMC_DAT_0, | ||
43 | GPIO109_MMC_DAT_1, | ||
44 | GPIO110_MMC_DAT_2, | ||
45 | GPIO111_MMC_DAT_3, | ||
46 | GPIO112_MMC_CMD, | ||
47 | GPIO0_GPIO, /* SD detect */ | ||
48 | |||
49 | /* FFUART */ | ||
50 | GPIO39_FFUART_TXD, | ||
51 | GPIO34_FFUART_RXD, | ||
52 | |||
53 | /* UHC */ | ||
54 | GPIO88_USBH1_PWR, | ||
55 | GPIO89_USBH1_PEN, | ||
56 | GPIO119_USBH2_PWR, | ||
57 | GPIO120_USBH2_PEN, | ||
58 | |||
59 | /* PCMCIA */ | ||
60 | GPIO85_nPCE_1, | ||
61 | GPIO54_nPCE_2, | ||
62 | GPIO55_nPREG, | ||
63 | GPIO50_nPIOR, | ||
64 | GPIO51_nPIOW, | ||
65 | GPIO49_nPWE, | ||
66 | GPIO48_nPOE, | ||
67 | GPIO57_nIOIS16, | ||
68 | GPIO56_nPWAIT, | ||
69 | GPIO104_PSKTSEL, | ||
70 | GPIO53_GPIO, /* RESET */ | ||
71 | GPIO83_GPIO, /* BVD1 */ | ||
72 | GPIO82_GPIO, /* BVD2 */ | ||
73 | GPIO1_GPIO, /* READY */ | ||
74 | GPIO84_GPIO, /* DETECT */ | ||
75 | GPIO107_GPIO, /* PPEN */ | ||
76 | |||
77 | /* I2C */ | ||
78 | GPIO117_I2C_SCL, | ||
79 | GPIO118_I2C_SDA, | ||
80 | }; | ||
81 | #else | ||
82 | static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {}; | ||
83 | #endif | ||
84 | |||
85 | #ifdef CONFIG_MACH_COLIBRI_PXA270_INCOME | ||
86 | static mfp_cfg_t income_pin_config[] __initdata = { | ||
87 | /* MMC */ | ||
88 | GPIO32_MMC_CLK, | ||
89 | GPIO92_MMC_DAT_0, | ||
90 | GPIO109_MMC_DAT_1, | ||
91 | GPIO110_MMC_DAT_2, | ||
92 | GPIO111_MMC_DAT_3, | ||
93 | GPIO112_MMC_CMD, | ||
94 | GPIO0_GPIO, /* SD detect */ | ||
95 | GPIO1_GPIO, /* SD read-only */ | ||
96 | |||
97 | /* FFUART */ | ||
98 | GPIO39_FFUART_TXD, | ||
99 | GPIO34_FFUART_RXD, | ||
100 | |||
101 | /* BFUART */ | ||
102 | GPIO42_BTUART_RXD, | ||
103 | GPIO43_BTUART_TXD, | ||
104 | GPIO45_BTUART_RTS, | ||
105 | |||
106 | /* STUART */ | ||
107 | GPIO46_STUART_RXD, | ||
108 | GPIO47_STUART_TXD, | ||
109 | |||
110 | /* UHC */ | ||
111 | GPIO88_USBH1_PWR, | ||
112 | GPIO89_USBH1_PEN, | ||
113 | |||
114 | /* LCD */ | ||
115 | GPIOxx_LCD_TFT_16BPP, | ||
116 | |||
117 | /* PWM */ | ||
118 | GPIO16_PWM0_OUT, | ||
119 | |||
120 | /* I2C */ | ||
121 | GPIO117_I2C_SCL, | ||
122 | GPIO118_I2C_SDA, | ||
123 | |||
124 | /* LED */ | ||
125 | GPIO54_GPIO, /* LED A */ | ||
126 | GPIO55_GPIO, /* LED B */ | ||
127 | }; | ||
128 | #else | ||
129 | static mfp_cfg_t income_pin_config[] __initdata = {}; | ||
130 | #endif | ||
131 | |||
132 | /****************************************************************************** | ||
36 | * Pin configuration | 133 | * Pin configuration |
37 | ******************************************************************************/ | 134 | ******************************************************************************/ |
38 | static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = { | 135 | static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = { |
@@ -184,10 +281,13 @@ static void __init colibri_pxa270_init(void) | |||
184 | colibri_pxa270_tsc_init(); | 281 | colibri_pxa270_tsc_init(); |
185 | 282 | ||
186 | switch (colibri_pxa270_baseboard) { | 283 | switch (colibri_pxa270_baseboard) { |
187 | case COLIBRI_PXA270_EVALBOARD: | 284 | case COLIBRI_EVALBOARD: |
188 | colibri_pxa270_evalboard_init(); | 285 | pxa2xx_mfp_config(ARRAY_AND_SIZE( |
286 | colibri_pxa270_evalboard_pin_config)); | ||
287 | colibri_evalboard_init(); | ||
189 | break; | 288 | break; |
190 | case COLIBRI_PXA270_INCOME: | 289 | case COLIBRI_PXA270_INCOME: |
290 | pxa2xx_mfp_config(ARRAY_AND_SIZE(income_pin_config)); | ||
191 | colibri_pxa270_income_boardinit(); | 291 | colibri_pxa270_income_boardinit(); |
192 | break; | 292 | break; |
193 | default: | 293 | default: |
@@ -209,7 +309,7 @@ static void __init colibri_pxa270_income_init(void) | |||
209 | MACHINE_START(COLIBRI, "Toradex Colibri PXA270") | 309 | MACHINE_START(COLIBRI, "Toradex Colibri PXA270") |
210 | .boot_params = COLIBRI_SDRAM_BASE + 0x100, | 310 | .boot_params = COLIBRI_SDRAM_BASE + 0x100, |
211 | .init_machine = colibri_pxa270_init, | 311 | .init_machine = colibri_pxa270_init, |
212 | .map_io = pxa_map_io, | 312 | .map_io = pxa27x_map_io, |
213 | .init_irq = pxa27x_init_irq, | 313 | .init_irq = pxa27x_init_irq, |
214 | .timer = &pxa_timer, | 314 | .timer = &pxa_timer, |
215 | MACHINE_END | 315 | MACHINE_END |
@@ -217,7 +317,7 @@ MACHINE_END | |||
217 | MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC") | 317 | MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC") |
218 | .boot_params = 0xa0000100, | 318 | .boot_params = 0xa0000100, |
219 | .init_machine = colibri_pxa270_income_init, | 319 | .init_machine = colibri_pxa270_income_init, |
220 | .map_io = pxa_map_io, | 320 | .map_io = pxa27x_map_io, |
221 | .init_irq = pxa27x_init_irq, | 321 | .init_irq = pxa27x_init_irq, |
222 | .timer = &pxa_timer, | 322 | .timer = &pxa_timer, |
223 | MACHINE_END | 323 | MACHINE_END |
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index a70b256591e6..fddb16d07eb0 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c | |||
@@ -31,9 +31,38 @@ | |||
31 | #include "generic.h" | 31 | #include "generic.h" |
32 | #include "devices.h" | 32 | #include "devices.h" |
33 | 33 | ||
34 | |||
35 | #ifdef CONFIG_MACH_COLIBRI_EVALBOARD | ||
36 | static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = { | ||
37 | /* MMC */ | ||
38 | GPIO7_MMC1_CLK, | ||
39 | GPIO14_MMC1_CMD, | ||
40 | GPIO3_MMC1_DAT0, | ||
41 | GPIO4_MMC1_DAT1, | ||
42 | GPIO5_MMC1_DAT2, | ||
43 | GPIO6_MMC1_DAT3, | ||
44 | GPIO39_GPIO, /* SD detect */ | ||
45 | |||
46 | /* UHC */ | ||
47 | GPIO0_2_USBH_PEN, | ||
48 | GPIO1_2_USBH_PWR, | ||
49 | GPIO77_USB_P3_1, | ||
50 | GPIO78_USB_P3_2, | ||
51 | GPIO79_USB_P3_3, | ||
52 | GPIO80_USB_P3_4, | ||
53 | GPIO81_USB_P3_5, | ||
54 | GPIO82_USB_P3_6, | ||
55 | |||
56 | /* I2C */ | ||
57 | GPIO21_I2C_SCL, | ||
58 | GPIO22_I2C_SDA, | ||
59 | }; | ||
60 | #else | ||
61 | static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = {}; | ||
62 | #endif | ||
63 | |||
34 | #if defined(CONFIG_AX88796) | 64 | #if defined(CONFIG_AX88796) |
35 | #define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO) | 65 | #define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO) |
36 | |||
37 | /* | 66 | /* |
38 | * Asix AX88796 Ethernet | 67 | * Asix AX88796 Ethernet |
39 | */ | 68 | */ |
@@ -80,35 +109,6 @@ static void __init colibri_pxa300_init_eth(void) | |||
80 | static inline void __init colibri_pxa300_init_eth(void) {} | 109 | static inline void __init colibri_pxa300_init_eth(void) {} |
81 | #endif /* CONFIG_AX88796 */ | 110 | #endif /* CONFIG_AX88796 */ |
82 | 111 | ||
83 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
84 | static mfp_cfg_t colibri_pxa300_usb_pin_config[] __initdata = { | ||
85 | GPIO0_2_USBH_PEN, | ||
86 | GPIO1_2_USBH_PWR, | ||
87 | }; | ||
88 | |||
89 | static struct pxaohci_platform_data colibri_pxa300_ohci_info = { | ||
90 | .port_mode = PMM_GLOBAL_MODE, | ||
91 | .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW, | ||
92 | }; | ||
93 | |||
94 | void __init colibri_pxa300_init_ohci(void) | ||
95 | { | ||
96 | pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_usb_pin_config)); | ||
97 | pxa_set_ohci_info(&colibri_pxa300_ohci_info); | ||
98 | } | ||
99 | #else | ||
100 | static inline void colibri_pxa300_init_ohci(void) {} | ||
101 | #endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */ | ||
102 | |||
103 | static mfp_cfg_t colibri_pxa300_mmc_pin_config[] __initdata = { | ||
104 | GPIO7_MMC1_CLK, | ||
105 | GPIO14_MMC1_CMD, | ||
106 | GPIO3_MMC1_DAT0, | ||
107 | GPIO4_MMC1_DAT1, | ||
108 | GPIO5_MMC1_DAT2, | ||
109 | GPIO6_MMC1_DAT3, | ||
110 | }; | ||
111 | |||
112 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | 112 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) |
113 | static mfp_cfg_t colibri_pxa300_lcd_pin_config[] __initdata = { | 113 | static mfp_cfg_t colibri_pxa300_lcd_pin_config[] __initdata = { |
114 | GPIO54_LCD_LDD_0, | 114 | GPIO54_LCD_LDD_0, |
@@ -171,24 +171,21 @@ static inline void colibri_pxa310_init_ac97(void) {} | |||
171 | 171 | ||
172 | void __init colibri_pxa300_init(void) | 172 | void __init colibri_pxa300_init(void) |
173 | { | 173 | { |
174 | pxa_set_ffuart_info(NULL); | ||
175 | pxa_set_btuart_info(NULL); | ||
176 | pxa_set_stuart_info(NULL); | ||
177 | |||
178 | colibri_pxa300_init_eth(); | 174 | colibri_pxa300_init_eth(); |
179 | colibri_pxa300_init_ohci(); | ||
180 | colibri_pxa3xx_init_nand(); | 175 | colibri_pxa3xx_init_nand(); |
181 | colibri_pxa300_init_lcd(); | 176 | colibri_pxa300_init_lcd(); |
182 | colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO39_GPIO)); | 177 | colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO39_GPIO)); |
183 | colibri_pxa310_init_ac97(); | 178 | colibri_pxa310_init_ac97(); |
184 | colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa300_mmc_pin_config), | 179 | |
185 | mfp_to_gpio(MFP_PIN_GPIO13)); | 180 | /* Evalboard init */ |
181 | pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_evalboard_pin_config)); | ||
182 | colibri_evalboard_init(); | ||
186 | } | 183 | } |
187 | 184 | ||
188 | MACHINE_START(COLIBRI300, "Toradex Colibri PXA300") | 185 | MACHINE_START(COLIBRI300, "Toradex Colibri PXA300") |
189 | .boot_params = COLIBRI_SDRAM_BASE + 0x100, | 186 | .boot_params = COLIBRI_SDRAM_BASE + 0x100, |
190 | .init_machine = colibri_pxa300_init, | 187 | .init_machine = colibri_pxa300_init, |
191 | .map_io = pxa_map_io, | 188 | .map_io = pxa3xx_map_io, |
192 | .init_irq = pxa3xx_init_irq, | 189 | .init_irq = pxa3xx_init_irq, |
193 | .timer = &pxa_timer, | 190 | .timer = &pxa_timer, |
194 | MACHINE_END | 191 | MACHINE_END |
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index ca5f29e2e9cd..ff9ff5f4fc47 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c | |||
@@ -35,9 +35,72 @@ | |||
35 | #include "generic.h" | 35 | #include "generic.h" |
36 | #include "devices.h" | 36 | #include "devices.h" |
37 | 37 | ||
38 | #ifdef CONFIG_MACH_COLIBRI_EVALBOARD | ||
39 | static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = { | ||
40 | /* MMC */ | ||
41 | GPIO22_MMC1_CLK, | ||
42 | GPIO23_MMC1_CMD, | ||
43 | GPIO18_MMC1_DAT0, | ||
44 | GPIO19_MMC1_DAT1, | ||
45 | GPIO20_MMC1_DAT2, | ||
46 | GPIO21_MMC1_DAT3, | ||
47 | GPIO28_GPIO, /* SD detect */ | ||
48 | |||
49 | /* UART 1 configuration (may be set by bootloader) */ | ||
50 | GPIO99_UART1_CTS, | ||
51 | GPIO104_UART1_RTS, | ||
52 | GPIO97_UART1_RXD, | ||
53 | GPIO98_UART1_TXD, | ||
54 | GPIO101_UART1_DTR, | ||
55 | GPIO103_UART1_DSR, | ||
56 | GPIO100_UART1_DCD, | ||
57 | GPIO102_UART1_RI, | ||
58 | |||
59 | /* UART 2 configuration */ | ||
60 | GPIO109_UART2_CTS, | ||
61 | GPIO112_UART2_RTS, | ||
62 | GPIO110_UART2_RXD, | ||
63 | GPIO111_UART2_TXD, | ||
64 | |||
65 | /* UART 3 configuration */ | ||
66 | GPIO30_UART3_RXD, | ||
67 | GPIO31_UART3_TXD, | ||
68 | |||
69 | /* UHC */ | ||
70 | GPIO2_2_USBH_PEN, | ||
71 | GPIO3_2_USBH_PWR, | ||
72 | |||
73 | /* I2C */ | ||
74 | GPIO32_I2C_SCL, | ||
75 | GPIO33_I2C_SDA, | ||
76 | |||
77 | /* PCMCIA */ | ||
78 | MFP_CFG(GPIO59, AF7), /* PRST ; AF7 to tristate */ | ||
79 | MFP_CFG(GPIO61, AF7), /* PCE1 ; AF7 to tristate */ | ||
80 | MFP_CFG(GPIO60, AF7), /* PCE2 ; AF7 to tristate */ | ||
81 | MFP_CFG(GPIO62, AF7), /* PCD ; AF7 to tristate */ | ||
82 | MFP_CFG(GPIO56, AF7), /* PSKTSEL ; AF7 to tristate */ | ||
83 | GPIO27_GPIO, /* RDnWR ; input/tristate */ | ||
84 | GPIO50_GPIO, /* PREG ; input/tristate */ | ||
85 | GPIO2_RDY, | ||
86 | GPIO5_NPIOR, | ||
87 | GPIO6_NPIOW, | ||
88 | GPIO7_NPIOS16, | ||
89 | GPIO8_NPWAIT, | ||
90 | GPIO29_GPIO, /* PRDY (READY GPIO) */ | ||
91 | GPIO57_GPIO, /* PPEN (POWER GPIO) */ | ||
92 | GPIO81_GPIO, /* PCD (DETECT GPIO) */ | ||
93 | GPIO77_GPIO, /* PRST (RESET GPIO) */ | ||
94 | GPIO53_GPIO, /* PBVD1 */ | ||
95 | GPIO79_GPIO, /* PBVD2 */ | ||
96 | GPIO54_GPIO, /* POE */ | ||
97 | }; | ||
98 | #else | ||
99 | static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = {}; | ||
100 | #endif | ||
101 | |||
38 | #if defined(CONFIG_AX88796) | 102 | #if defined(CONFIG_AX88796) |
39 | #define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO) | 103 | #define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO) |
40 | |||
41 | /* | 104 | /* |
42 | * Asix AX88796 Ethernet | 105 | * Asix AX88796 Ethernet |
43 | */ | 106 | */ |
@@ -84,26 +147,6 @@ static void __init colibri_pxa320_init_eth(void) | |||
84 | static inline void __init colibri_pxa320_init_eth(void) {} | 147 | static inline void __init colibri_pxa320_init_eth(void) {} |
85 | #endif /* CONFIG_AX88796 */ | 148 | #endif /* CONFIG_AX88796 */ |
86 | 149 | ||
87 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
88 | static mfp_cfg_t colibri_pxa320_usb_pin_config[] __initdata = { | ||
89 | GPIO2_2_USBH_PEN, | ||
90 | GPIO3_2_USBH_PWR, | ||
91 | }; | ||
92 | |||
93 | static struct pxaohci_platform_data colibri_pxa320_ohci_info = { | ||
94 | .port_mode = PMM_GLOBAL_MODE, | ||
95 | .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW, | ||
96 | }; | ||
97 | |||
98 | void __init colibri_pxa320_init_ohci(void) | ||
99 | { | ||
100 | pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_usb_pin_config)); | ||
101 | pxa_set_ohci_info(&colibri_pxa320_ohci_info); | ||
102 | } | ||
103 | #else | ||
104 | static inline void colibri_pxa320_init_ohci(void) {} | ||
105 | #endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */ | ||
106 | |||
107 | #if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE) | 150 | #if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE) |
108 | static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = { | 151 | static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = { |
109 | .gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96), | 152 | .gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96), |
@@ -140,15 +183,6 @@ static void __init colibri_pxa320_init_udc(void) | |||
140 | static inline void colibri_pxa320_init_udc(void) {} | 183 | static inline void colibri_pxa320_init_udc(void) {} |
141 | #endif | 184 | #endif |
142 | 185 | ||
143 | static mfp_cfg_t colibri_pxa320_mmc_pin_config[] __initdata = { | ||
144 | GPIO22_MMC1_CLK, | ||
145 | GPIO23_MMC1_CMD, | ||
146 | GPIO18_MMC1_DAT0, | ||
147 | GPIO19_MMC1_DAT1, | ||
148 | GPIO20_MMC1_DAT2, | ||
149 | GPIO21_MMC1_DAT3 | ||
150 | }; | ||
151 | |||
152 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | 186 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) |
153 | static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = { | 187 | static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = { |
154 | GPIO6_2_LCD_LDD_0, | 188 | GPIO6_2_LCD_LDD_0, |
@@ -205,59 +239,24 @@ static inline void __init colibri_pxa320_init_ac97(void) | |||
205 | static inline void colibri_pxa320_init_ac97(void) {} | 239 | static inline void colibri_pxa320_init_ac97(void) {} |
206 | #endif | 240 | #endif |
207 | 241 | ||
208 | /* | ||
209 | * The following configuration is verified to work with the Toradex Orchid | ||
210 | * carrier board | ||
211 | */ | ||
212 | static mfp_cfg_t colibri_pxa320_uart_pin_config[] __initdata = { | ||
213 | /* UART 1 configuration (may be set by bootloader) */ | ||
214 | GPIO99_UART1_CTS, | ||
215 | GPIO104_UART1_RTS, | ||
216 | GPIO97_UART1_RXD, | ||
217 | GPIO98_UART1_TXD, | ||
218 | GPIO101_UART1_DTR, | ||
219 | GPIO103_UART1_DSR, | ||
220 | GPIO100_UART1_DCD, | ||
221 | GPIO102_UART1_RI, | ||
222 | |||
223 | /* UART 2 configuration */ | ||
224 | GPIO109_UART2_CTS, | ||
225 | GPIO112_UART2_RTS, | ||
226 | GPIO110_UART2_RXD, | ||
227 | GPIO111_UART2_TXD, | ||
228 | |||
229 | /* UART 3 configuration */ | ||
230 | GPIO30_UART3_RXD, | ||
231 | GPIO31_UART3_TXD, | ||
232 | }; | ||
233 | |||
234 | static void __init colibri_pxa320_init_uart(void) | ||
235 | { | ||
236 | pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_uart_pin_config)); | ||
237 | } | ||
238 | |||
239 | void __init colibri_pxa320_init(void) | 242 | void __init colibri_pxa320_init(void) |
240 | { | 243 | { |
241 | pxa_set_ffuart_info(NULL); | ||
242 | pxa_set_btuart_info(NULL); | ||
243 | pxa_set_stuart_info(NULL); | ||
244 | |||
245 | colibri_pxa320_init_eth(); | 244 | colibri_pxa320_init_eth(); |
246 | colibri_pxa320_init_ohci(); | ||
247 | colibri_pxa3xx_init_nand(); | 245 | colibri_pxa3xx_init_nand(); |
248 | colibri_pxa320_init_lcd(); | 246 | colibri_pxa320_init_lcd(); |
249 | colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO)); | 247 | colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO)); |
250 | colibri_pxa320_init_ac97(); | 248 | colibri_pxa320_init_ac97(); |
251 | colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa320_mmc_pin_config), | ||
252 | mfp_to_gpio(MFP_PIN_GPIO28)); | ||
253 | colibri_pxa320_init_uart(); | ||
254 | colibri_pxa320_init_udc(); | 249 | colibri_pxa320_init_udc(); |
250 | |||
251 | /* Evalboard init */ | ||
252 | pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_evalboard_pin_config)); | ||
253 | colibri_evalboard_init(); | ||
255 | } | 254 | } |
256 | 255 | ||
257 | MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") | 256 | MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") |
258 | .boot_params = COLIBRI_SDRAM_BASE + 0x100, | 257 | .boot_params = COLIBRI_SDRAM_BASE + 0x100, |
259 | .init_machine = colibri_pxa320_init, | 258 | .init_machine = colibri_pxa320_init, |
260 | .map_io = pxa_map_io, | 259 | .map_io = pxa3xx_map_io, |
261 | .init_irq = pxa3xx_init_irq, | 260 | .init_irq = pxa3xx_init_irq, |
262 | .timer = &pxa_timer, | 261 | .timer = &pxa_timer, |
263 | MACHINE_END | 262 | MACHINE_END |
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index 199afa2ae303..96b2d9fbfef0 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c | |||
@@ -64,55 +64,6 @@ void __init colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data) | |||
64 | } | 64 | } |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) | ||
68 | static int mmc_detect_pin; | ||
69 | |||
70 | static int colibri_pxa3xx_mci_init(struct device *dev, | ||
71 | irq_handler_t colibri_mmc_detect_int, | ||
72 | void *data) | ||
73 | { | ||
74 | int ret; | ||
75 | |||
76 | ret = gpio_request(mmc_detect_pin, "mmc card detect"); | ||
77 | if (ret) | ||
78 | return ret; | ||
79 | |||
80 | gpio_direction_input(mmc_detect_pin); | ||
81 | ret = request_irq(gpio_to_irq(mmc_detect_pin), colibri_mmc_detect_int, | ||
82 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
83 | "MMC card detect", data); | ||
84 | if (ret) { | ||
85 | gpio_free(mmc_detect_pin); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static void colibri_pxa3xx_mci_exit(struct device *dev, void *data) | ||
93 | { | ||
94 | free_irq(mmc_detect_pin, data); | ||
95 | gpio_free(gpio_to_irq(mmc_detect_pin)); | ||
96 | } | ||
97 | |||
98 | static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = { | ||
99 | .detect_delay_ms = 200, | ||
100 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | ||
101 | .init = colibri_pxa3xx_mci_init, | ||
102 | .exit = colibri_pxa3xx_mci_exit, | ||
103 | .gpio_card_detect = -1, | ||
104 | .gpio_card_ro = -1, | ||
105 | .gpio_power = -1, | ||
106 | }; | ||
107 | |||
108 | void __init colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin) | ||
109 | { | ||
110 | pxa3xx_mfp_config(pins, len); | ||
111 | mmc_detect_pin = detect_pin; | ||
112 | pxa_set_mci_info(&colibri_pxa3xx_mci_platform_data); | ||
113 | } | ||
114 | #endif /* CONFIG_MMC_PXA || CONFIG_MMC_PXA_MODULE */ | ||
115 | |||
116 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | 67 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) |
117 | static int lcd_bl_pin; | 68 | static int lcd_bl_pin; |
118 | 69 | ||
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 821229acabe6..9f3e5af0a0db 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
@@ -721,7 +721,7 @@ static void __init fixup_corgi(struct machine_desc *desc, | |||
721 | #ifdef CONFIG_MACH_CORGI | 721 | #ifdef CONFIG_MACH_CORGI |
722 | MACHINE_START(CORGI, "SHARP Corgi") | 722 | MACHINE_START(CORGI, "SHARP Corgi") |
723 | .fixup = fixup_corgi, | 723 | .fixup = fixup_corgi, |
724 | .map_io = pxa_map_io, | 724 | .map_io = pxa25x_map_io, |
725 | .init_irq = pxa25x_init_irq, | 725 | .init_irq = pxa25x_init_irq, |
726 | .init_machine = corgi_init, | 726 | .init_machine = corgi_init, |
727 | .timer = &pxa_timer, | 727 | .timer = &pxa_timer, |
@@ -731,7 +731,7 @@ MACHINE_END | |||
731 | #ifdef CONFIG_MACH_SHEPHERD | 731 | #ifdef CONFIG_MACH_SHEPHERD |
732 | MACHINE_START(SHEPHERD, "SHARP Shepherd") | 732 | MACHINE_START(SHEPHERD, "SHARP Shepherd") |
733 | .fixup = fixup_corgi, | 733 | .fixup = fixup_corgi, |
734 | .map_io = pxa_map_io, | 734 | .map_io = pxa25x_map_io, |
735 | .init_irq = pxa25x_init_irq, | 735 | .init_irq = pxa25x_init_irq, |
736 | .init_machine = corgi_init, | 736 | .init_machine = corgi_init, |
737 | .timer = &pxa_timer, | 737 | .timer = &pxa_timer, |
@@ -741,7 +741,7 @@ MACHINE_END | |||
741 | #ifdef CONFIG_MACH_HUSKY | 741 | #ifdef CONFIG_MACH_HUSKY |
742 | MACHINE_START(HUSKY, "SHARP Husky") | 742 | MACHINE_START(HUSKY, "SHARP Husky") |
743 | .fixup = fixup_corgi, | 743 | .fixup = fixup_corgi, |
744 | .map_io = pxa_map_io, | 744 | .map_io = pxa25x_map_io, |
745 | .init_irq = pxa25x_init_irq, | 745 | .init_irq = pxa25x_init_irq, |
746 | .init_machine = corgi_init, | 746 | .init_machine = corgi_init, |
747 | .timer = &pxa_timer, | 747 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 58093d9e07be..6a7aeab42f6c 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c | |||
@@ -38,8 +38,10 @@ | |||
38 | #include <linux/cpufreq.h> | 38 | #include <linux/cpufreq.h> |
39 | #include <linux/err.h> | 39 | #include <linux/err.h> |
40 | #include <linux/regulator/consumer.h> | 40 | #include <linux/regulator/consumer.h> |
41 | #include <linux/io.h> | ||
41 | 42 | ||
42 | #include <mach/pxa2xx-regs.h> | 43 | #include <mach/pxa2xx-regs.h> |
44 | #include <mach/smemc.h> | ||
43 | 45 | ||
44 | #ifdef DEBUG | 46 | #ifdef DEBUG |
45 | static unsigned int freq_debug; | 47 | static unsigned int freq_debug; |
@@ -242,7 +244,7 @@ static void pxa27x_guess_max_freq(void) | |||
242 | 244 | ||
243 | static void init_sdram_rows(void) | 245 | static void init_sdram_rows(void) |
244 | { | 246 | { |
245 | uint32_t mdcnfg = MDCNFG; | 247 | uint32_t mdcnfg = __raw_readl(MDCNFG); |
246 | unsigned int drac2 = 0, drac0 = 0; | 248 | unsigned int drac2 = 0, drac0 = 0; |
247 | 249 | ||
248 | if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3)) | 250 | if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3)) |
@@ -331,8 +333,8 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
331 | * we need to preset the smaller DRI before the change. If we're | 333 | * we need to preset the smaller DRI before the change. If we're |
332 | * speeding up we need to set the larger DRI value after the change. | 334 | * speeding up we need to set the larger DRI value after the change. |
333 | */ | 335 | */ |
334 | preset_mdrefr = postset_mdrefr = MDREFR; | 336 | preset_mdrefr = postset_mdrefr = __raw_readl(MDREFR); |
335 | if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) { | 337 | if ((preset_mdrefr & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) { |
336 | preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK); | 338 | preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK); |
337 | preset_mdrefr |= mdrefr_dri(new_freq_mem); | 339 | preset_mdrefr |= mdrefr_dri(new_freq_mem); |
338 | } | 340 | } |
@@ -370,7 +372,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
370 | 3: nop \n\ | 372 | 3: nop \n\ |
371 | " | 373 | " |
372 | : "=&r" (unused) | 374 | : "=&r" (unused) |
373 | : "r" (&MDREFR), "r" (cclkcfg), | 375 | : "r" (MDREFR), "r" (cclkcfg), |
374 | "r" (preset_mdrefr), "r" (postset_mdrefr) | 376 | "r" (preset_mdrefr), "r" (postset_mdrefr) |
375 | : "r4", "r5"); | 377 | : "r4", "r5"); |
376 | local_irq_restore(flags); | 378 | local_irq_restore(flags); |
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index 57cacaff194d..a305424a967d 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <mach/ohci.h> | 27 | #include <mach/ohci.h> |
28 | #include <mach/pxa2xx-regs.h> | 28 | #include <mach/pxa2xx-regs.h> |
29 | #include <mach/audio.h> | 29 | #include <mach/audio.h> |
30 | #include <mach/smemc.h> | ||
30 | 31 | ||
31 | #include "generic.h" | 32 | #include "generic.h" |
32 | #include "devices.h" | 33 | #include "devices.h" |
@@ -255,9 +256,9 @@ static struct platform_device *devices[] __initdata = { | |||
255 | static void __init csb726_init(void) | 256 | static void __init csb726_init(void) |
256 | { | 257 | { |
257 | pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config)); | 258 | pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config)); |
258 | /* MSC1 = 0x7ffc3ffc; *//* LAN9215/EXP_CS */ | 259 | /* __raw_writel(0x7ffc3ffc, MSC1); *//* LAN9215/EXP_CS */ |
259 | /* MSC2 = 0x06697ff4; *//* none/SM501 */ | 260 | /* __raw_writel(0x06697ff4, MSC2); *//* none/SM501 */ |
260 | MSC2 = (MSC2 & ~0xffff) | 0x7ff4; /* SM501 */ | 261 | __raw_writel((__raw_readl(MSC2) & ~0xffff) | 0x7ff4, MSC2); /* SM501 */ |
261 | 262 | ||
262 | pxa_set_ffuart_info(NULL); | 263 | pxa_set_ffuart_info(NULL); |
263 | pxa_set_btuart_info(NULL); | 264 | pxa_set_btuart_info(NULL); |
@@ -273,7 +274,7 @@ static void __init csb726_init(void) | |||
273 | 274 | ||
274 | MACHINE_START(CSB726, "Cogent CSB726") | 275 | MACHINE_START(CSB726, "Cogent CSB726") |
275 | .boot_params = 0xa0000100, | 276 | .boot_params = 0xa0000100, |
276 | .map_io = pxa_map_io, | 277 | .map_io = pxa27x_map_io, |
277 | .init_irq = pxa27x_init_irq, | 278 | .init_irq = pxa27x_init_irq, |
278 | .init_machine = csb726_init, | 279 | .init_machine = csb726_init, |
279 | .timer = &pxa_timer, | 280 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index aaa1166df964..022c2fa4af04 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c | |||
@@ -342,27 +342,6 @@ struct platform_device pxa27x_device_i2c_power = { | |||
342 | }; | 342 | }; |
343 | #endif | 343 | #endif |
344 | 344 | ||
345 | #ifdef CONFIG_PXA3xx | ||
346 | static struct resource pxa3xx_resources_i2c_power[] = { | ||
347 | { | ||
348 | .start = 0x40f500c0, | ||
349 | .end = 0x40f500d3, | ||
350 | .flags = IORESOURCE_MEM, | ||
351 | }, { | ||
352 | .start = IRQ_PWRI2C, | ||
353 | .end = IRQ_PWRI2C, | ||
354 | .flags = IORESOURCE_IRQ, | ||
355 | }, | ||
356 | }; | ||
357 | |||
358 | struct platform_device pxa3xx_device_i2c_power = { | ||
359 | .name = "pxa3xx-pwri2c", | ||
360 | .id = 1, | ||
361 | .resource = pxa3xx_resources_i2c_power, | ||
362 | .num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power), | ||
363 | }; | ||
364 | #endif | ||
365 | |||
366 | static struct resource pxai2s_resources[] = { | 345 | static struct resource pxai2s_resources[] = { |
367 | { | 346 | { |
368 | .start = 0x40400000, | 347 | .start = 0x40400000, |
@@ -633,30 +612,35 @@ struct platform_device pxa25x_device_assp = { | |||
633 | #endif /* CONFIG_PXA25x */ | 612 | #endif /* CONFIG_PXA25x */ |
634 | 613 | ||
635 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | 614 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) |
636 | 615 | static struct resource pxa27x_resource_camera[] = { | |
637 | static struct resource pxa27x_resource_keypad[] = { | ||
638 | [0] = { | 616 | [0] = { |
639 | .start = 0x41500000, | 617 | .start = 0x50000000, |
640 | .end = 0x4150004c, | 618 | .end = 0x50000fff, |
641 | .flags = IORESOURCE_MEM, | 619 | .flags = IORESOURCE_MEM, |
642 | }, | 620 | }, |
643 | [1] = { | 621 | [1] = { |
644 | .start = IRQ_KEYPAD, | 622 | .start = IRQ_CAMERA, |
645 | .end = IRQ_KEYPAD, | 623 | .end = IRQ_CAMERA, |
646 | .flags = IORESOURCE_IRQ, | 624 | .flags = IORESOURCE_IRQ, |
647 | }, | 625 | }, |
648 | }; | 626 | }; |
649 | 627 | ||
650 | struct platform_device pxa27x_device_keypad = { | 628 | static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32); |
651 | .name = "pxa27x-keypad", | 629 | |
652 | .id = -1, | 630 | static struct platform_device pxa27x_device_camera = { |
653 | .resource = pxa27x_resource_keypad, | 631 | .name = "pxa27x-camera", |
654 | .num_resources = ARRAY_SIZE(pxa27x_resource_keypad), | 632 | .id = 0, /* This is used to put cameras on this interface */ |
633 | .dev = { | ||
634 | .dma_mask = &pxa27x_dma_mask_camera, | ||
635 | .coherent_dma_mask = 0xffffffff, | ||
636 | }, | ||
637 | .num_resources = ARRAY_SIZE(pxa27x_resource_camera), | ||
638 | .resource = pxa27x_resource_camera, | ||
655 | }; | 639 | }; |
656 | 640 | ||
657 | void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info) | 641 | void __init pxa_set_camera_info(struct pxacamera_platform_data *info) |
658 | { | 642 | { |
659 | pxa_register_device(&pxa27x_device_keypad, info); | 643 | pxa_register_device(&pxa27x_device_camera, info); |
660 | } | 644 | } |
661 | 645 | ||
662 | static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32); | 646 | static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32); |
@@ -689,6 +673,33 @@ void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) | |||
689 | { | 673 | { |
690 | pxa_register_device(&pxa27x_device_ohci, info); | 674 | pxa_register_device(&pxa27x_device_ohci, info); |
691 | } | 675 | } |
676 | #endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ | ||
677 | |||
678 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) | ||
679 | static struct resource pxa27x_resource_keypad[] = { | ||
680 | [0] = { | ||
681 | .start = 0x41500000, | ||
682 | .end = 0x4150004c, | ||
683 | .flags = IORESOURCE_MEM, | ||
684 | }, | ||
685 | [1] = { | ||
686 | .start = IRQ_KEYPAD, | ||
687 | .end = IRQ_KEYPAD, | ||
688 | .flags = IORESOURCE_IRQ, | ||
689 | }, | ||
690 | }; | ||
691 | |||
692 | struct platform_device pxa27x_device_keypad = { | ||
693 | .name = "pxa27x-keypad", | ||
694 | .id = -1, | ||
695 | .resource = pxa27x_resource_keypad, | ||
696 | .num_resources = ARRAY_SIZE(pxa27x_resource_keypad), | ||
697 | }; | ||
698 | |||
699 | void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info) | ||
700 | { | ||
701 | pxa_register_device(&pxa27x_device_keypad, info); | ||
702 | } | ||
692 | 703 | ||
693 | static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32); | 704 | static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32); |
694 | 705 | ||
@@ -833,79 +844,9 @@ struct platform_device pxa27x_device_pwm1 = { | |||
833 | .resource = pxa27x_resource_pwm1, | 844 | .resource = pxa27x_resource_pwm1, |
834 | .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1), | 845 | .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1), |
835 | }; | 846 | }; |
836 | 847 | #endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA95x*/ | |
837 | static struct resource pxa27x_resource_camera[] = { | ||
838 | [0] = { | ||
839 | .start = 0x50000000, | ||
840 | .end = 0x50000fff, | ||
841 | .flags = IORESOURCE_MEM, | ||
842 | }, | ||
843 | [1] = { | ||
844 | .start = IRQ_CAMERA, | ||
845 | .end = IRQ_CAMERA, | ||
846 | .flags = IORESOURCE_IRQ, | ||
847 | }, | ||
848 | }; | ||
849 | |||
850 | static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32); | ||
851 | |||
852 | static struct platform_device pxa27x_device_camera = { | ||
853 | .name = "pxa27x-camera", | ||
854 | .id = 0, /* This is used to put cameras on this interface */ | ||
855 | .dev = { | ||
856 | .dma_mask = &pxa27x_dma_mask_camera, | ||
857 | .coherent_dma_mask = 0xffffffff, | ||
858 | }, | ||
859 | .num_resources = ARRAY_SIZE(pxa27x_resource_camera), | ||
860 | .resource = pxa27x_resource_camera, | ||
861 | }; | ||
862 | |||
863 | void __init pxa_set_camera_info(struct pxacamera_platform_data *info) | ||
864 | { | ||
865 | pxa_register_device(&pxa27x_device_camera, info); | ||
866 | } | ||
867 | #endif /* CONFIG_PXA27x || CONFIG_PXA3xx */ | ||
868 | 848 | ||
869 | #ifdef CONFIG_PXA3xx | 849 | #ifdef CONFIG_PXA3xx |
870 | static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32); | ||
871 | |||
872 | static struct resource pxa3xx_resource_ssp4[] = { | ||
873 | [0] = { | ||
874 | .start = 0x41a00000, | ||
875 | .end = 0x41a0003f, | ||
876 | .flags = IORESOURCE_MEM, | ||
877 | }, | ||
878 | [1] = { | ||
879 | .start = IRQ_SSP4, | ||
880 | .end = IRQ_SSP4, | ||
881 | .flags = IORESOURCE_IRQ, | ||
882 | }, | ||
883 | [2] = { | ||
884 | /* DRCMR for RX */ | ||
885 | .start = 2, | ||
886 | .end = 2, | ||
887 | .flags = IORESOURCE_DMA, | ||
888 | }, | ||
889 | [3] = { | ||
890 | /* DRCMR for TX */ | ||
891 | .start = 3, | ||
892 | .end = 3, | ||
893 | .flags = IORESOURCE_DMA, | ||
894 | }, | ||
895 | }; | ||
896 | |||
897 | struct platform_device pxa3xx_device_ssp4 = { | ||
898 | /* PXA3xx SSP is basically equivalent to PXA27x */ | ||
899 | .name = "pxa27x-ssp", | ||
900 | .id = 3, | ||
901 | .dev = { | ||
902 | .dma_mask = &pxa3xx_ssp4_dma_mask, | ||
903 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
904 | }, | ||
905 | .resource = pxa3xx_resource_ssp4, | ||
906 | .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4), | ||
907 | }; | ||
908 | |||
909 | static struct resource pxa3xx_resources_mci2[] = { | 850 | static struct resource pxa3xx_resources_mci2[] = { |
910 | [0] = { | 851 | [0] = { |
911 | .start = 0x42000000, | 852 | .start = 0x42000000, |
@@ -984,6 +925,54 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info) | |||
984 | pxa_register_device(&pxa3xx_device_mci3, info); | 925 | pxa_register_device(&pxa3xx_device_mci3, info); |
985 | } | 926 | } |
986 | 927 | ||
928 | static struct resource pxa3xx_resources_gcu[] = { | ||
929 | { | ||
930 | .start = 0x54000000, | ||
931 | .end = 0x54000fff, | ||
932 | .flags = IORESOURCE_MEM, | ||
933 | }, | ||
934 | { | ||
935 | .start = IRQ_GCU, | ||
936 | .end = IRQ_GCU, | ||
937 | .flags = IORESOURCE_IRQ, | ||
938 | }, | ||
939 | }; | ||
940 | |||
941 | static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32); | ||
942 | |||
943 | struct platform_device pxa3xx_device_gcu = { | ||
944 | .name = "pxa3xx-gcu", | ||
945 | .id = -1, | ||
946 | .num_resources = ARRAY_SIZE(pxa3xx_resources_gcu), | ||
947 | .resource = pxa3xx_resources_gcu, | ||
948 | .dev = { | ||
949 | .dma_mask = &pxa3xx_gcu_dmamask, | ||
950 | .coherent_dma_mask = 0xffffffff, | ||
951 | }, | ||
952 | }; | ||
953 | |||
954 | #endif /* CONFIG_PXA3xx */ | ||
955 | |||
956 | #if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) | ||
957 | static struct resource pxa3xx_resources_i2c_power[] = { | ||
958 | { | ||
959 | .start = 0x40f500c0, | ||
960 | .end = 0x40f500d3, | ||
961 | .flags = IORESOURCE_MEM, | ||
962 | }, { | ||
963 | .start = IRQ_PWRI2C, | ||
964 | .end = IRQ_PWRI2C, | ||
965 | .flags = IORESOURCE_IRQ, | ||
966 | }, | ||
967 | }; | ||
968 | |||
969 | struct platform_device pxa3xx_device_i2c_power = { | ||
970 | .name = "pxa3xx-pwri2c", | ||
971 | .id = 1, | ||
972 | .resource = pxa3xx_resources_i2c_power, | ||
973 | .num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power), | ||
974 | }; | ||
975 | |||
987 | static struct resource pxa3xx_resources_nand[] = { | 976 | static struct resource pxa3xx_resources_nand[] = { |
988 | [0] = { | 977 | [0] = { |
989 | .start = 0x43100000, | 978 | .start = 0x43100000, |
@@ -1027,33 +1016,45 @@ void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info) | |||
1027 | pxa_register_device(&pxa3xx_device_nand, info); | 1016 | pxa_register_device(&pxa3xx_device_nand, info); |
1028 | } | 1017 | } |
1029 | 1018 | ||
1030 | static struct resource pxa3xx_resources_gcu[] = { | 1019 | static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32); |
1031 | { | 1020 | |
1032 | .start = 0x54000000, | 1021 | static struct resource pxa3xx_resource_ssp4[] = { |
1033 | .end = 0x54000fff, | 1022 | [0] = { |
1023 | .start = 0x41a00000, | ||
1024 | .end = 0x41a0003f, | ||
1034 | .flags = IORESOURCE_MEM, | 1025 | .flags = IORESOURCE_MEM, |
1035 | }, | 1026 | }, |
1036 | { | 1027 | [1] = { |
1037 | .start = IRQ_GCU, | 1028 | .start = IRQ_SSP4, |
1038 | .end = IRQ_GCU, | 1029 | .end = IRQ_SSP4, |
1039 | .flags = IORESOURCE_IRQ, | 1030 | .flags = IORESOURCE_IRQ, |
1040 | }, | 1031 | }, |
1032 | [2] = { | ||
1033 | /* DRCMR for RX */ | ||
1034 | .start = 2, | ||
1035 | .end = 2, | ||
1036 | .flags = IORESOURCE_DMA, | ||
1037 | }, | ||
1038 | [3] = { | ||
1039 | /* DRCMR for TX */ | ||
1040 | .start = 3, | ||
1041 | .end = 3, | ||
1042 | .flags = IORESOURCE_DMA, | ||
1043 | }, | ||
1041 | }; | 1044 | }; |
1042 | 1045 | ||
1043 | static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32); | 1046 | struct platform_device pxa3xx_device_ssp4 = { |
1044 | 1047 | /* PXA3xx SSP is basically equivalent to PXA27x */ | |
1045 | struct platform_device pxa3xx_device_gcu = { | 1048 | .name = "pxa27x-ssp", |
1046 | .name = "pxa3xx-gcu", | 1049 | .id = 3, |
1047 | .id = -1, | ||
1048 | .num_resources = ARRAY_SIZE(pxa3xx_resources_gcu), | ||
1049 | .resource = pxa3xx_resources_gcu, | ||
1050 | .dev = { | 1050 | .dev = { |
1051 | .dma_mask = &pxa3xx_gcu_dmamask, | 1051 | .dma_mask = &pxa3xx_ssp4_dma_mask, |
1052 | .coherent_dma_mask = 0xffffffff, | 1052 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1053 | }, | 1053 | }, |
1054 | .resource = pxa3xx_resource_ssp4, | ||
1055 | .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4), | ||
1054 | }; | 1056 | }; |
1055 | 1057 | #endif /* CONFIG_PXA3xx || CONFIG_PXA95x */ | |
1056 | #endif /* CONFIG_PXA3xx */ | ||
1057 | 1058 | ||
1058 | /* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. | 1059 | /* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. |
1059 | * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */ | 1060 | * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */ |
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index ed0dbfdb22ed..4cefd1d18afd 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -1300,7 +1300,7 @@ static void __init em_x270_init(void) | |||
1300 | 1300 | ||
1301 | MACHINE_START(EM_X270, "Compulab EM-X270") | 1301 | MACHINE_START(EM_X270, "Compulab EM-X270") |
1302 | .boot_params = 0xa0000100, | 1302 | .boot_params = 0xa0000100, |
1303 | .map_io = pxa_map_io, | 1303 | .map_io = pxa27x_map_io, |
1304 | .init_irq = pxa27x_init_irq, | 1304 | .init_irq = pxa27x_init_irq, |
1305 | .timer = &pxa_timer, | 1305 | .timer = &pxa_timer, |
1306 | .init_machine = em_x270_init, | 1306 | .init_machine = em_x270_init, |
@@ -1308,7 +1308,7 @@ MACHINE_END | |||
1308 | 1308 | ||
1309 | MACHINE_START(EXEDA, "Compulab eXeda") | 1309 | MACHINE_START(EXEDA, "Compulab eXeda") |
1310 | .boot_params = 0xa0000100, | 1310 | .boot_params = 0xa0000100, |
1311 | .map_io = pxa_map_io, | 1311 | .map_io = pxa27x_map_io, |
1312 | .init_irq = pxa27x_init_irq, | 1312 | .init_irq = pxa27x_init_irq, |
1313 | .timer = &pxa_timer, | 1313 | .timer = &pxa_timer, |
1314 | .init_machine = em_x270_init, | 1314 | .init_machine = em_x270_init, |
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index b25690ccadc4..edca0a043293 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c | |||
@@ -181,7 +181,7 @@ static void __init e330_init(void) | |||
181 | MACHINE_START(E330, "Toshiba e330") | 181 | MACHINE_START(E330, "Toshiba e330") |
182 | /* Maintainer: Ian Molton (spyro@f2s.com) */ | 182 | /* Maintainer: Ian Molton (spyro@f2s.com) */ |
183 | .boot_params = 0xa0000100, | 183 | .boot_params = 0xa0000100, |
184 | .map_io = pxa_map_io, | 184 | .map_io = pxa25x_map_io, |
185 | .nr_irqs = ESERIES_NR_IRQS, | 185 | .nr_irqs = ESERIES_NR_IRQS, |
186 | .init_irq = pxa25x_init_irq, | 186 | .init_irq = pxa25x_init_irq, |
187 | .fixup = eseries_fixup, | 187 | .fixup = eseries_fixup, |
@@ -230,7 +230,7 @@ static void __init e350_init(void) | |||
230 | MACHINE_START(E350, "Toshiba e350") | 230 | MACHINE_START(E350, "Toshiba e350") |
231 | /* Maintainer: Ian Molton (spyro@f2s.com) */ | 231 | /* Maintainer: Ian Molton (spyro@f2s.com) */ |
232 | .boot_params = 0xa0000100, | 232 | .boot_params = 0xa0000100, |
233 | .map_io = pxa_map_io, | 233 | .map_io = pxa25x_map_io, |
234 | .nr_irqs = ESERIES_NR_IRQS, | 234 | .nr_irqs = ESERIES_NR_IRQS, |
235 | .init_irq = pxa25x_init_irq, | 235 | .init_irq = pxa25x_init_irq, |
236 | .fixup = eseries_fixup, | 236 | .fixup = eseries_fixup, |
@@ -352,7 +352,7 @@ static void __init e400_init(void) | |||
352 | MACHINE_START(E400, "Toshiba e400") | 352 | MACHINE_START(E400, "Toshiba e400") |
353 | /* Maintainer: Ian Molton (spyro@f2s.com) */ | 353 | /* Maintainer: Ian Molton (spyro@f2s.com) */ |
354 | .boot_params = 0xa0000100, | 354 | .boot_params = 0xa0000100, |
355 | .map_io = pxa_map_io, | 355 | .map_io = pxa25x_map_io, |
356 | .nr_irqs = ESERIES_NR_IRQS, | 356 | .nr_irqs = ESERIES_NR_IRQS, |
357 | .init_irq = pxa25x_init_irq, | 357 | .init_irq = pxa25x_init_irq, |
358 | .fixup = eseries_fixup, | 358 | .fixup = eseries_fixup, |
@@ -540,7 +540,7 @@ static void __init e740_init(void) | |||
540 | MACHINE_START(E740, "Toshiba e740") | 540 | MACHINE_START(E740, "Toshiba e740") |
541 | /* Maintainer: Ian Molton (spyro@f2s.com) */ | 541 | /* Maintainer: Ian Molton (spyro@f2s.com) */ |
542 | .boot_params = 0xa0000100, | 542 | .boot_params = 0xa0000100, |
543 | .map_io = pxa_map_io, | 543 | .map_io = pxa25x_map_io, |
544 | .nr_irqs = ESERIES_NR_IRQS, | 544 | .nr_irqs = ESERIES_NR_IRQS, |
545 | .init_irq = pxa25x_init_irq, | 545 | .init_irq = pxa25x_init_irq, |
546 | .fixup = eseries_fixup, | 546 | .fixup = eseries_fixup, |
@@ -731,7 +731,7 @@ static void __init e750_init(void) | |||
731 | MACHINE_START(E750, "Toshiba e750") | 731 | MACHINE_START(E750, "Toshiba e750") |
732 | /* Maintainer: Ian Molton (spyro@f2s.com) */ | 732 | /* Maintainer: Ian Molton (spyro@f2s.com) */ |
733 | .boot_params = 0xa0000100, | 733 | .boot_params = 0xa0000100, |
734 | .map_io = pxa_map_io, | 734 | .map_io = pxa25x_map_io, |
735 | .nr_irqs = ESERIES_NR_IRQS, | 735 | .nr_irqs = ESERIES_NR_IRQS, |
736 | .init_irq = pxa25x_init_irq, | 736 | .init_irq = pxa25x_init_irq, |
737 | .fixup = eseries_fixup, | 737 | .fixup = eseries_fixup, |
@@ -926,7 +926,7 @@ static void __init e800_init(void) | |||
926 | MACHINE_START(E800, "Toshiba e800") | 926 | MACHINE_START(E800, "Toshiba e800") |
927 | /* Maintainer: Ian Molton (spyro@f2s.com) */ | 927 | /* Maintainer: Ian Molton (spyro@f2s.com) */ |
928 | .boot_params = 0xa0000100, | 928 | .boot_params = 0xa0000100, |
929 | .map_io = pxa_map_io, | 929 | .map_io = pxa25x_map_io, |
930 | .nr_irqs = ESERIES_NR_IRQS, | 930 | .nr_irqs = ESERIES_NR_IRQS, |
931 | .init_irq = pxa25x_init_irq, | 931 | .init_irq = pxa25x_init_irq, |
932 | .fixup = eseries_fixup, | 932 | .fixup = eseries_fixup, |
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 142c711f4cda..87cec0abe5b0 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c | |||
@@ -798,7 +798,7 @@ static void __init a780_init(void) | |||
798 | 798 | ||
799 | MACHINE_START(EZX_A780, "Motorola EZX A780") | 799 | MACHINE_START(EZX_A780, "Motorola EZX A780") |
800 | .boot_params = 0xa0000100, | 800 | .boot_params = 0xa0000100, |
801 | .map_io = pxa_map_io, | 801 | .map_io = pxa27x_map_io, |
802 | .nr_irqs = EZX_NR_IRQS, | 802 | .nr_irqs = EZX_NR_IRQS, |
803 | .init_irq = pxa27x_init_irq, | 803 | .init_irq = pxa27x_init_irq, |
804 | .timer = &pxa_timer, | 804 | .timer = &pxa_timer, |
@@ -863,7 +863,7 @@ static void __init e680_init(void) | |||
863 | 863 | ||
864 | MACHINE_START(EZX_E680, "Motorola EZX E680") | 864 | MACHINE_START(EZX_E680, "Motorola EZX E680") |
865 | .boot_params = 0xa0000100, | 865 | .boot_params = 0xa0000100, |
866 | .map_io = pxa_map_io, | 866 | .map_io = pxa27x_map_io, |
867 | .nr_irqs = EZX_NR_IRQS, | 867 | .nr_irqs = EZX_NR_IRQS, |
868 | .init_irq = pxa27x_init_irq, | 868 | .init_irq = pxa27x_init_irq, |
869 | .timer = &pxa_timer, | 869 | .timer = &pxa_timer, |
@@ -928,7 +928,7 @@ static void __init a1200_init(void) | |||
928 | 928 | ||
929 | MACHINE_START(EZX_A1200, "Motorola EZX A1200") | 929 | MACHINE_START(EZX_A1200, "Motorola EZX A1200") |
930 | .boot_params = 0xa0000100, | 930 | .boot_params = 0xa0000100, |
931 | .map_io = pxa_map_io, | 931 | .map_io = pxa27x_map_io, |
932 | .nr_irqs = EZX_NR_IRQS, | 932 | .nr_irqs = EZX_NR_IRQS, |
933 | .init_irq = pxa27x_init_irq, | 933 | .init_irq = pxa27x_init_irq, |
934 | .timer = &pxa_timer, | 934 | .timer = &pxa_timer, |
@@ -1118,7 +1118,7 @@ static void __init a910_init(void) | |||
1118 | 1118 | ||
1119 | MACHINE_START(EZX_A910, "Motorola EZX A910") | 1119 | MACHINE_START(EZX_A910, "Motorola EZX A910") |
1120 | .boot_params = 0xa0000100, | 1120 | .boot_params = 0xa0000100, |
1121 | .map_io = pxa_map_io, | 1121 | .map_io = pxa27x_map_io, |
1122 | .nr_irqs = EZX_NR_IRQS, | 1122 | .nr_irqs = EZX_NR_IRQS, |
1123 | .init_irq = pxa27x_init_irq, | 1123 | .init_irq = pxa27x_init_irq, |
1124 | .timer = &pxa_timer, | 1124 | .timer = &pxa_timer, |
@@ -1183,7 +1183,7 @@ static void __init e6_init(void) | |||
1183 | 1183 | ||
1184 | MACHINE_START(EZX_E6, "Motorola EZX E6") | 1184 | MACHINE_START(EZX_E6, "Motorola EZX E6") |
1185 | .boot_params = 0xa0000100, | 1185 | .boot_params = 0xa0000100, |
1186 | .map_io = pxa_map_io, | 1186 | .map_io = pxa27x_map_io, |
1187 | .nr_irqs = EZX_NR_IRQS, | 1187 | .nr_irqs = EZX_NR_IRQS, |
1188 | .init_irq = pxa27x_init_irq, | 1188 | .init_irq = pxa27x_init_irq, |
1189 | .timer = &pxa_timer, | 1189 | .timer = &pxa_timer, |
@@ -1222,7 +1222,7 @@ static void __init e2_init(void) | |||
1222 | 1222 | ||
1223 | MACHINE_START(EZX_E2, "Motorola EZX E2") | 1223 | MACHINE_START(EZX_E2, "Motorola EZX E2") |
1224 | .boot_params = 0xa0000100, | 1224 | .boot_params = 0xa0000100, |
1225 | .map_io = pxa_map_io, | 1225 | .map_io = pxa27x_map_io, |
1226 | .nr_irqs = EZX_NR_IRQS, | 1226 | .nr_irqs = EZX_NR_IRQS, |
1227 | .init_irq = pxa27x_init_irq, | 1227 | .init_irq = pxa27x_init_irq, |
1228 | .timer = &pxa_timer, | 1228 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 6451e9c3a93f..d6e15f71fc09 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #include <mach/reset.h> | 29 | #include <mach/reset.h> |
30 | #include <mach/gpio.h> | 30 | #include <mach/gpio.h> |
31 | #include <mach/smemc.h> | ||
32 | #include <mach/pxa3xx-regs.h> | ||
31 | 33 | ||
32 | #include "generic.h" | 34 | #include "generic.h" |
33 | 35 | ||
@@ -35,9 +37,10 @@ void clear_reset_status(unsigned int mask) | |||
35 | { | 37 | { |
36 | if (cpu_is_pxa2xx()) | 38 | if (cpu_is_pxa2xx()) |
37 | pxa2xx_clear_reset_status(mask); | 39 | pxa2xx_clear_reset_status(mask); |
38 | 40 | else { | |
39 | if (cpu_is_pxa3xx()) | 41 | /* RESET_STATUS_* has a 1:1 mapping with ARSR */ |
40 | pxa3xx_clear_reset_status(mask); | 42 | ARSR = mask; |
43 | } | ||
41 | } | 44 | } |
42 | 45 | ||
43 | unsigned long get_clock_tick_rate(void) | 46 | unsigned long get_clock_tick_rate(void) |
@@ -71,47 +74,17 @@ unsigned int get_clk_frequency_khz(int info) | |||
71 | EXPORT_SYMBOL(get_clk_frequency_khz); | 74 | EXPORT_SYMBOL(get_clk_frequency_khz); |
72 | 75 | ||
73 | /* | 76 | /* |
74 | * Return the current memory clock frequency in units of 10kHz | ||
75 | */ | ||
76 | unsigned int get_memclk_frequency_10khz(void) | ||
77 | { | ||
78 | if (cpu_is_pxa25x()) | ||
79 | return pxa25x_get_memclk_frequency_10khz(); | ||
80 | else if (cpu_is_pxa27x()) | ||
81 | return pxa27x_get_memclk_frequency_10khz(); | ||
82 | return 0; | ||
83 | } | ||
84 | EXPORT_SYMBOL(get_memclk_frequency_10khz); | ||
85 | |||
86 | /* | ||
87 | * Intel PXA2xx internal register mapping. | 77 | * Intel PXA2xx internal register mapping. |
88 | * | 78 | * |
89 | * Note 1: not all PXA2xx variants implement all those addresses. | 79 | * Note: virtual 0xfffe0000-0xffffffff is reserved for the vector table |
90 | * | 80 | * and cache flush area. |
91 | * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table | ||
92 | * and cache flush area. | ||
93 | */ | 81 | */ |
94 | static struct map_desc standard_io_desc[] __initdata = { | 82 | static struct map_desc common_io_desc[] __initdata = { |
95 | { /* Devs */ | 83 | { /* Devs */ |
96 | .virtual = 0xf2000000, | 84 | .virtual = 0xf2000000, |
97 | .pfn = __phys_to_pfn(0x40000000), | 85 | .pfn = __phys_to_pfn(0x40000000), |
98 | .length = 0x02000000, | 86 | .length = 0x02000000, |
99 | .type = MT_DEVICE | 87 | .type = MT_DEVICE |
100 | }, { /* Mem Ctl */ | ||
101 | .virtual = 0xf6000000, | ||
102 | .pfn = __phys_to_pfn(0x48000000), | ||
103 | .length = 0x00200000, | ||
104 | .type = MT_DEVICE | ||
105 | }, { /* Camera */ | ||
106 | .virtual = 0xfa000000, | ||
107 | .pfn = __phys_to_pfn(0x50000000), | ||
108 | .length = 0x00100000, | ||
109 | .type = MT_DEVICE | ||
110 | }, { /* IMem ctl */ | ||
111 | .virtual = 0xfe000000, | ||
112 | .pfn = __phys_to_pfn(0x58000000), | ||
113 | .length = 0x00100000, | ||
114 | .type = MT_DEVICE | ||
115 | }, { /* UNCACHED_PHYS_0 */ | 88 | }, { /* UNCACHED_PHYS_0 */ |
116 | .virtual = 0xff000000, | 89 | .virtual = 0xff000000, |
117 | .pfn = __phys_to_pfn(0x00000000), | 90 | .pfn = __phys_to_pfn(0x00000000), |
@@ -122,6 +95,5 @@ static struct map_desc standard_io_desc[] __initdata = { | |||
122 | 95 | ||
123 | void __init pxa_map_io(void) | 96 | void __init pxa_map_io(void) |
124 | { | 97 | { |
125 | iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); | 98 | iotable_init(ARRAY_AND_SIZE(common_io_desc)); |
126 | get_clk_frequency_khz(1); | ||
127 | } | 99 | } |
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 4b1ad2769ed7..6205dc9a2b9d 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h | |||
@@ -20,7 +20,12 @@ extern void __init pxa26x_init_irq(void); | |||
20 | #endif | 20 | #endif |
21 | extern void __init pxa27x_init_irq(void); | 21 | extern void __init pxa27x_init_irq(void); |
22 | extern void __init pxa3xx_init_irq(void); | 22 | extern void __init pxa3xx_init_irq(void); |
23 | extern void __init pxa95x_init_irq(void); | ||
24 | |||
23 | extern void __init pxa_map_io(void); | 25 | extern void __init pxa_map_io(void); |
26 | extern void __init pxa25x_map_io(void); | ||
27 | extern void __init pxa27x_map_io(void); | ||
28 | extern void __init pxa3xx_map_io(void); | ||
24 | 29 | ||
25 | extern unsigned int get_clk_frequency_khz(int info); | 30 | extern unsigned int get_clk_frequency_khz(int info); |
26 | 31 | ||
@@ -32,18 +37,14 @@ extern unsigned int get_clk_frequency_khz(int info); | |||
32 | 37 | ||
33 | #ifdef CONFIG_PXA25x | 38 | #ifdef CONFIG_PXA25x |
34 | extern unsigned pxa25x_get_clk_frequency_khz(int); | 39 | extern unsigned pxa25x_get_clk_frequency_khz(int); |
35 | extern unsigned pxa25x_get_memclk_frequency_10khz(void); | ||
36 | #else | 40 | #else |
37 | #define pxa25x_get_clk_frequency_khz(x) (0) | 41 | #define pxa25x_get_clk_frequency_khz(x) (0) |
38 | #define pxa25x_get_memclk_frequency_10khz() (0) | ||
39 | #endif | 42 | #endif |
40 | 43 | ||
41 | #ifdef CONFIG_PXA27x | 44 | #ifdef CONFIG_PXA27x |
42 | extern unsigned pxa27x_get_clk_frequency_khz(int); | 45 | extern unsigned pxa27x_get_clk_frequency_khz(int); |
43 | extern unsigned pxa27x_get_memclk_frequency_10khz(void); | ||
44 | #else | 46 | #else |
45 | #define pxa27x_get_clk_frequency_khz(x) (0) | 47 | #define pxa27x_get_clk_frequency_khz(x) (0) |
46 | #define pxa27x_get_memclk_frequency_10khz() (0) | ||
47 | #endif | 48 | #endif |
48 | 49 | ||
49 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | 50 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) |
@@ -54,10 +55,8 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {} | |||
54 | 55 | ||
55 | #ifdef CONFIG_PXA3xx | 56 | #ifdef CONFIG_PXA3xx |
56 | extern unsigned pxa3xx_get_clk_frequency_khz(int); | 57 | extern unsigned pxa3xx_get_clk_frequency_khz(int); |
57 | extern void pxa3xx_clear_reset_status(unsigned int); | ||
58 | #else | 58 | #else |
59 | #define pxa3xx_get_clk_frequency_khz(x) (0) | 59 | #define pxa3xx_get_clk_frequency_khz(x) (0) |
60 | static inline void pxa3xx_clear_reset_status(unsigned int mask) {} | ||
61 | #endif | 60 | #endif |
62 | 61 | ||
63 | extern struct sysdev_class pxa_irq_sysclass; | 62 | extern struct sysdev_class pxa_irq_sysclass; |
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 1e2a9a13aec1..6fd319ea5284 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c | |||
@@ -225,7 +225,7 @@ static void __init gumstix_init(void) | |||
225 | 225 | ||
226 | MACHINE_START(GUMSTIX, "Gumstix") | 226 | MACHINE_START(GUMSTIX, "Gumstix") |
227 | .boot_params = 0xa0000100, /* match u-boot bi_boot_params */ | 227 | .boot_params = 0xa0000100, /* match u-boot bi_boot_params */ |
228 | .map_io = pxa_map_io, | 228 | .map_io = pxa25x_map_io, |
229 | .init_irq = pxa25x_init_irq, | 229 | .init_irq = pxa25x_init_irq, |
230 | .timer = &pxa_timer, | 230 | .timer = &pxa_timer, |
231 | .init_machine = gumstix_init, | 231 | .init_machine = gumstix_init, |
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c index 7057a1f46db4..657db469de1f 100644 --- a/arch/arm/mach-pxa/h5000.c +++ b/arch/arm/mach-pxa/h5000.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <mach/pxa25x.h> | 32 | #include <mach/pxa25x.h> |
33 | #include <mach/h5000.h> | 33 | #include <mach/h5000.h> |
34 | #include <mach/udc.h> | 34 | #include <mach/udc.h> |
35 | #include <mach/smemc.h> | ||
35 | 36 | ||
36 | #include "generic.h" | 37 | #include "generic.h" |
37 | 38 | ||
@@ -172,11 +173,11 @@ static unsigned long h5000_pin_config[] __initdata = { | |||
172 | 173 | ||
173 | static void fix_msc(void) | 174 | static void fix_msc(void) |
174 | { | 175 | { |
175 | MSC0 = 0x129c24f2; | 176 | __raw_writel(0x129c24f2, MSC0); |
176 | MSC1 = 0x7ff424fa; | 177 | __raw_writel(0x7ff424fa, MSC1); |
177 | MSC2 = 0x7ff47ff4; | 178 | __raw_writel(0x7ff47ff4, MSC2); |
178 | 179 | ||
179 | MDREFR |= 0x02080000; | 180 | __raw_writel(__raw_readl(MDREFR) | 0x02080000, MDREFR); |
180 | } | 181 | } |
181 | 182 | ||
182 | /* | 183 | /* |
@@ -202,7 +203,7 @@ static void __init h5000_init(void) | |||
202 | 203 | ||
203 | MACHINE_START(H5400, "HP iPAQ H5000") | 204 | MACHINE_START(H5400, "HP iPAQ H5000") |
204 | .boot_params = 0xa0000100, | 205 | .boot_params = 0xa0000100, |
205 | .map_io = pxa_map_io, | 206 | .map_io = pxa25x_map_io, |
206 | .init_irq = pxa25x_init_irq, | 207 | .init_irq = pxa25x_init_irq, |
207 | .timer = &pxa_timer, | 208 | .timer = &pxa_timer, |
208 | .init_machine = h5000_init, | 209 | .init_machine = h5000_init, |
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c index 01b7f07ebad2..e8603eba54bd 100644 --- a/arch/arm/mach-pxa/himalaya.c +++ b/arch/arm/mach-pxa/himalaya.c | |||
@@ -160,7 +160,7 @@ static void __init himalaya_init(void) | |||
160 | 160 | ||
161 | MACHINE_START(HIMALAYA, "HTC Himalaya") | 161 | MACHINE_START(HIMALAYA, "HTC Himalaya") |
162 | .boot_params = 0xa0000100, | 162 | .boot_params = 0xa0000100, |
163 | .map_io = pxa_map_io, | 163 | .map_io = pxa25x_map_io, |
164 | .init_irq = pxa25x_init_irq, | 164 | .init_irq = pxa25x_init_irq, |
165 | .init_machine = himalaya_init, | 165 | .init_machine = himalaya_init, |
166 | .timer = &pxa_timer, | 166 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 76d93a25bab6..cacb21b7014d 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c | |||
@@ -871,7 +871,7 @@ static void __init hx4700_init(void) | |||
871 | 871 | ||
872 | MACHINE_START(H4700, "HP iPAQ HX4700") | 872 | MACHINE_START(H4700, "HP iPAQ HX4700") |
873 | .boot_params = 0xa0000100, | 873 | .boot_params = 0xa0000100, |
874 | .map_io = pxa_map_io, | 874 | .map_io = pxa27x_map_io, |
875 | .nr_irqs = HX4700_NR_IRQS, | 875 | .nr_irqs = HX4700_NR_IRQS, |
876 | .init_irq = pxa27x_init_irq, | 876 | .init_irq = pxa27x_init_irq, |
877 | .init_machine = hx4700_init, | 877 | .init_machine = hx4700_init, |
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index d51ee3d25e70..ac6ee12e400e 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c | |||
@@ -192,7 +192,7 @@ static void __init icontrol_init(void) | |||
192 | 192 | ||
193 | MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") | 193 | MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") |
194 | .boot_params = 0xa0000100, | 194 | .boot_params = 0xa0000100, |
195 | .map_io = pxa_map_io, | 195 | .map_io = pxa3xx_map_io, |
196 | .init_irq = pxa3xx_init_irq, | 196 | .init_irq = pxa3xx_init_irq, |
197 | .timer = &pxa_timer, | 197 | .timer = &pxa_timer, |
198 | .init_machine = icontrol_init | 198 | .init_machine = icontrol_init |
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index e773dceeabc6..dd40e4a9291c 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c | |||
@@ -187,7 +187,7 @@ static struct map_desc idp_io_desc[] __initdata = { | |||
187 | 187 | ||
188 | static void __init idp_map_io(void) | 188 | static void __init idp_map_io(void) |
189 | { | 189 | { |
190 | pxa_map_io(); | 190 | pxa25x_map_io(); |
191 | iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc)); | 191 | iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc)); |
192 | } | 192 | } |
193 | 193 | ||
diff --git a/arch/arm/mach-pxa/include/mach/addr-map.h b/arch/arm/mach-pxa/include/mach/addr-map.h new file mode 100644 index 000000000000..f4c03659168c --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/addr-map.h | |||
@@ -0,0 +1,48 @@ | |||
1 | #ifndef __ASM_MACH_ADDR_MAP_H | ||
2 | #define __ASM_MACH_ADDR_MAP_H | ||
3 | |||
4 | /* | ||
5 | * Chip Selects | ||
6 | */ | ||
7 | #define PXA_CS0_PHYS 0x00000000 | ||
8 | #define PXA_CS1_PHYS 0x04000000 | ||
9 | #define PXA_CS2_PHYS 0x08000000 | ||
10 | #define PXA_CS3_PHYS 0x0C000000 | ||
11 | #define PXA_CS4_PHYS 0x10000000 | ||
12 | #define PXA_CS5_PHYS 0x14000000 | ||
13 | |||
14 | #define PXA300_CS0_PHYS 0x00000000 /* PXA300/PXA310 _only_ */ | ||
15 | #define PXA300_CS1_PHYS 0x30000000 /* PXA300/PXA310 _only_ */ | ||
16 | #define PXA3xx_CS2_PHYS 0x10000000 | ||
17 | #define PXA3xx_CS3_PHYS 0x14000000 | ||
18 | |||
19 | /* | ||
20 | * Peripheral Bus | ||
21 | */ | ||
22 | #define PERIPH_PHYS 0x40000000 | ||
23 | #define PERIPH_VIRT 0xf2000000 | ||
24 | #define PERIPH_SIZE 0x02000000 | ||
25 | |||
26 | /* | ||
27 | * Static Memory Controller (w/ SDRAM controls on PXA25x/PXA27x) | ||
28 | */ | ||
29 | #define PXA2XX_SMEMC_PHYS 0x48000000 | ||
30 | #define PXA3XX_SMEMC_PHYS 0x4a000000 | ||
31 | #define SMEMC_VIRT 0xf6000000 | ||
32 | #define SMEMC_SIZE 0x00100000 | ||
33 | |||
34 | /* | ||
35 | * Dynamic Memory Controller (only on PXA3xx) | ||
36 | */ | ||
37 | #define DMEMC_PHYS 0x48100000 | ||
38 | #define DMEMC_VIRT 0xf6100000 | ||
39 | #define DMEMC_SIZE 0x00100000 | ||
40 | |||
41 | /* | ||
42 | * Internal Memory Controller (PXA27x and later) | ||
43 | */ | ||
44 | #define IMEMC_PHYS 0x58000000 | ||
45 | #define IMEMC_VIRT 0xfe000000 | ||
46 | #define IMEMC_SIZE 0x00100000 | ||
47 | |||
48 | #endif /* __ASM_MACH_ADDR_MAP_H */ | ||
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h index 561562b4360b..7074e76146c9 100644 --- a/arch/arm/mach-pxa/include/mach/balloon3.h +++ b/arch/arm/mach-pxa/include/mach/balloon3.h | |||
@@ -26,6 +26,8 @@ enum balloon3_features { | |||
26 | #define BALLOON3_FPGA_VIRT (0xf1000000) /* as per balloon2 */ | 26 | #define BALLOON3_FPGA_VIRT (0xf1000000) /* as per balloon2 */ |
27 | #define BALLOON3_FPGA_LENGTH 0x01000000 | 27 | #define BALLOON3_FPGA_LENGTH 0x01000000 |
28 | 28 | ||
29 | #define BALLOON3_FPGA_SETnCLR (0x1000) | ||
30 | |||
29 | /* FPGA / CPLD registers for CF socket */ | 31 | /* FPGA / CPLD registers for CF socket */ |
30 | #define BALLOON3_CF_STATUS_REG (BALLOON3_FPGA_VIRT + 0x00e00008) | 32 | #define BALLOON3_CF_STATUS_REG (BALLOON3_FPGA_VIRT + 0x00e00008) |
31 | #define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008) | 33 | #define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008) |
@@ -35,7 +37,7 @@ enum balloon3_features { | |||
35 | #define BALLOON3_NAND_BASE (PXA_CS4_PHYS + 0x00e00000) | 37 | #define BALLOON3_NAND_BASE (PXA_CS4_PHYS + 0x00e00000) |
36 | #define BALLOON3_NAND_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000) | 38 | #define BALLOON3_NAND_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000) |
37 | #define BALLOON3_NAND_CONTROL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010) | 39 | #define BALLOON3_NAND_CONTROL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010) |
38 | #define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00010) | 40 | #define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00014) |
39 | #define BALLOON3_NAND_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00014) | 41 | #define BALLOON3_NAND_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00014) |
40 | 42 | ||
41 | /* fpga/cpld interrupt control register */ | 43 | /* fpga/cpld interrupt control register */ |
@@ -174,7 +176,7 @@ enum balloon3_features { | |||
174 | #define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ) | 176 | #define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ) |
175 | #define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD) | 177 | #define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD) |
176 | 178 | ||
177 | #define BALLOON3_NR_IRQS (IRQ_BOARD_START + 4) | 179 | #define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16) |
178 | 180 | ||
179 | extern int balloon3_has(enum balloon3_features feature); | 181 | extern int balloon3_has(enum balloon3_features feature); |
180 | 182 | ||
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h index 58dada11054f..388a96f1ef93 100644 --- a/arch/arm/mach-pxa/include/mach/colibri.h +++ b/arch/arm/mach-pxa/include/mach/colibri.h | |||
@@ -9,14 +9,14 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | enum { | 11 | enum { |
12 | COLIBRI_PXA270_EVALBOARD = 0, | 12 | COLIBRI_EVALBOARD = 0, |
13 | COLIBRI_PXA270_INCOME, | 13 | COLIBRI_PXA270_INCOME, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | #if defined(CONFIG_MACH_COLIBRI_PXA270_EVALBOARD) | 16 | #if defined(CONFIG_MACH_COLIBRI_EVALBOARD) |
17 | extern void colibri_pxa270_evalboard_init(void); | 17 | extern void colibri_evalboard_init(void); |
18 | #else | 18 | #else |
19 | static inline void colibri_pxa270_evalboard_init(void) {} | 19 | static inline void colibri_evalboard_init(void) {} |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #if defined(CONFIG_MACH_COLIBRI_PXA270_INCOME) | 22 | #if defined(CONFIG_MACH_COLIBRI_PXA270_INCOME) |
@@ -59,5 +59,11 @@ static inline void colibri_pxa3xx_init_nand(void) {} | |||
59 | #define GPIO0_COLIBRI_PXA270_SD_DETECT 0 | 59 | #define GPIO0_COLIBRI_PXA270_SD_DETECT 0 |
60 | #define GPIO113_COLIBRI_PXA270_TS_IRQ 113 | 60 | #define GPIO113_COLIBRI_PXA270_TS_IRQ 113 |
61 | 61 | ||
62 | /* GPIO definitions for Colibri PXA300/310 */ | ||
63 | #define GPIO39_COLIBRI_PXA300_SD_DETECT 39 | ||
64 | |||
65 | /* GPIO definitions for Colibri PXA320 */ | ||
66 | #define GPIO28_COLIBRI_PXA320_SD_DETECT 28 | ||
67 | |||
62 | #endif /* _COLIBRI_H_ */ | 68 | #endif /* _COLIBRI_H_ */ |
63 | 69 | ||
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 814f1458a06a..6957ba56025b 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #ifndef __ASM_ARCH_HARDWARE_H | 13 | #ifndef __ASM_ARCH_HARDWARE_H |
14 | #define __ASM_ARCH_HARDWARE_H | 14 | #define __ASM_ARCH_HARDWARE_H |
15 | 15 | ||
16 | #include <mach/addr-map.h> | ||
17 | |||
16 | /* | 18 | /* |
17 | * Workarounds for at least 2 errata so far require this. | 19 | * Workarounds for at least 2 errata so far require this. |
18 | * The mapping is set in mach-pxa/generic.c. | 20 | * The mapping is set in mach-pxa/generic.c. |
@@ -193,14 +195,15 @@ | |||
193 | #define __cpu_is_pxa935(id) (0) | 195 | #define __cpu_is_pxa935(id) (0) |
194 | #endif | 196 | #endif |
195 | 197 | ||
196 | #ifdef CONFIG_CPU_PXA950 | 198 | #ifdef CONFIG_CPU_PXA955 |
197 | #define __cpu_is_pxa950(id) \ | 199 | #define __cpu_is_pxa955(id) \ |
198 | ({ \ | 200 | ({ \ |
199 | unsigned int _id = (id) >> 4 & 0xfff; \ | 201 | unsigned int _id = (id) >> 4 & 0xfff; \ |
200 | _id == 0x697; \ | 202 | _id == 0x581 || _id == 0xc08 \ |
201 | }) | 203 | || _id == 0xb76; \ |
204 | }) | ||
202 | #else | 205 | #else |
203 | #define __cpu_is_pxa950(id) (0) | 206 | #define __cpu_is_pxa955(id) (0) |
204 | #endif | 207 | #endif |
205 | 208 | ||
206 | #define cpu_is_pxa210() \ | 209 | #define cpu_is_pxa210() \ |
@@ -253,16 +256,15 @@ | |||
253 | __cpu_is_pxa935(read_cpuid_id()); \ | 256 | __cpu_is_pxa935(read_cpuid_id()); \ |
254 | }) | 257 | }) |
255 | 258 | ||
256 | #define cpu_is_pxa950() \ | 259 | #define cpu_is_pxa955() \ |
257 | ({ \ | 260 | ({ \ |
258 | __cpu_is_pxa950(read_cpuid_id()); \ | 261 | __cpu_is_pxa955(read_cpuid_id()); \ |
259 | }) | 262 | }) |
260 | 263 | ||
261 | 264 | ||
262 | /* | 265 | /* |
263 | * CPUID Core Generation Bit | 266 | * CPUID Core Generation Bit |
264 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x | 267 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x |
265 | * == 0x3 for pxa300/pxa310/pxa320 | ||
266 | */ | 268 | */ |
267 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | 269 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) |
268 | #define __cpu_is_pxa2xx(id) \ | 270 | #define __cpu_is_pxa2xx(id) \ |
@@ -277,8 +279,10 @@ | |||
277 | #ifdef CONFIG_PXA3xx | 279 | #ifdef CONFIG_PXA3xx |
278 | #define __cpu_is_pxa3xx(id) \ | 280 | #define __cpu_is_pxa3xx(id) \ |
279 | ({ \ | 281 | ({ \ |
280 | unsigned int _id = (id) >> 13 & 0x7; \ | 282 | __cpu_is_pxa300(id) \ |
281 | _id == 0x3; \ | 283 | || __cpu_is_pxa310(id) \ |
284 | || __cpu_is_pxa320(id) \ | ||
285 | || __cpu_is_pxa93x(id); \ | ||
282 | }) | 286 | }) |
283 | #else | 287 | #else |
284 | #define __cpu_is_pxa3xx(id) (0) | 288 | #define __cpu_is_pxa3xx(id) (0) |
@@ -287,13 +291,22 @@ | |||
287 | #if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) | 291 | #if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) |
288 | #define __cpu_is_pxa93x(id) \ | 292 | #define __cpu_is_pxa93x(id) \ |
289 | ({ \ | 293 | ({ \ |
290 | unsigned int _id = (id) >> 4 & 0xfff; \ | 294 | __cpu_is_pxa930(id) \ |
291 | _id == 0x683 || _id == 0x693; \ | 295 | || __cpu_is_pxa935(id); \ |
292 | }) | 296 | }) |
293 | #else | 297 | #else |
294 | #define __cpu_is_pxa93x(id) (0) | 298 | #define __cpu_is_pxa93x(id) (0) |
295 | #endif | 299 | #endif |
296 | 300 | ||
301 | #ifdef CONFIG_PXA95x | ||
302 | #define __cpu_is_pxa95x(id) \ | ||
303 | ({ \ | ||
304 | __cpu_is_pxa955(id); \ | ||
305 | }) | ||
306 | #else | ||
307 | #define __cpu_is_pxa95x(id) (0) | ||
308 | #endif | ||
309 | |||
297 | #define cpu_is_pxa2xx() \ | 310 | #define cpu_is_pxa2xx() \ |
298 | ({ \ | 311 | ({ \ |
299 | __cpu_is_pxa2xx(read_cpuid_id()); \ | 312 | __cpu_is_pxa2xx(read_cpuid_id()); \ |
@@ -308,6 +321,12 @@ | |||
308 | ({ \ | 321 | ({ \ |
309 | __cpu_is_pxa93x(read_cpuid_id()); \ | 322 | __cpu_is_pxa93x(read_cpuid_id()); \ |
310 | }) | 323 | }) |
324 | |||
325 | #define cpu_is_pxa95x() \ | ||
326 | ({ \ | ||
327 | __cpu_is_pxa95x(read_cpuid_id()); \ | ||
328 | }) | ||
329 | |||
311 | /* | 330 | /* |
312 | * return current memory and LCD clock frequency in units of 10kHz | 331 | * return current memory and LCD clock frequency in units of 10kHz |
313 | */ | 332 | */ |
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index d372caa75dc7..a4285fc00878 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h | |||
@@ -21,16 +21,14 @@ | |||
21 | 21 | ||
22 | #define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x)) | 22 | #define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x)) |
23 | 23 | ||
24 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
25 | #define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */ | 24 | #define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */ |
26 | #define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */ | 25 | #define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */ |
27 | #define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI) */ | 26 | #define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI,PXA27x) */ |
28 | #define IRQ_USBH1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI) */ | 27 | #define IRQ_USBH1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI,PXA27x) */ |
29 | #define IRQ_KEYPAD PXA_IRQ(4) /* Key pad controller */ | 28 | #define IRQ_KEYPAD PXA_IRQ(4) /* Key pad controller */ |
30 | #define IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt */ | 29 | #define IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt (PXA27x) */ |
30 | #define IRQ_ACIPC0 PXA_IRQ(5) /* AP-CP Communication (PXA930) */ | ||
31 | #define IRQ_PWRI2C PXA_IRQ(6) /* Power I2C interrupt */ | 31 | #define IRQ_PWRI2C PXA_IRQ(6) /* Power I2C interrupt */ |
32 | #endif | ||
33 | |||
34 | #define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error (PXA26x) */ | 32 | #define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error (PXA26x) */ |
35 | #define IRQ_OST_4_11 PXA_IRQ(7) /* OS timer 4-11 matches (PXA27x) */ | 33 | #define IRQ_OST_4_11 PXA_IRQ(7) /* OS timer 4-11 matches (PXA27x) */ |
36 | #define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */ | 34 | #define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */ |
@@ -38,7 +36,8 @@ | |||
38 | #define IRQ_GPIO_2_x PXA_IRQ(10) /* GPIO[2-x] Edge Detect */ | 36 | #define IRQ_GPIO_2_x PXA_IRQ(10) /* GPIO[2-x] Edge Detect */ |
39 | #define IRQ_USB PXA_IRQ(11) /* USB Service */ | 37 | #define IRQ_USB PXA_IRQ(11) /* USB Service */ |
40 | #define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */ | 38 | #define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */ |
41 | #define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */ | 39 | #define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt (PXA27x) */ |
40 | #define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request (PXA3xx) */ | ||
42 | #define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */ | 41 | #define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */ |
43 | #define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request (PXA25x) */ | 42 | #define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request (PXA25x) */ |
44 | #define IRQ_USIM PXA_IRQ(15) /* Smart Card interface interrupt (PXA27x) */ | 43 | #define IRQ_USIM PXA_IRQ(15) /* Smart Card interface interrupt (PXA27x) */ |
@@ -47,6 +46,7 @@ | |||
47 | #define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */ | 46 | #define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */ |
48 | #define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */ | 47 | #define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */ |
49 | #define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */ | 48 | #define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */ |
49 | #define IRQ_ACIPC2 PXA_IRQ(19) /* AP-CP Communication (PXA930) */ | ||
50 | #define IRQ_STUART PXA_IRQ(20) /* STUART Transmit/Receive/Error */ | 50 | #define IRQ_STUART PXA_IRQ(20) /* STUART Transmit/Receive/Error */ |
51 | #define IRQ_BTUART PXA_IRQ(21) /* BTUART Transmit/Receive/Error */ | 51 | #define IRQ_BTUART PXA_IRQ(21) /* BTUART Transmit/Receive/Error */ |
52 | #define IRQ_FFUART PXA_IRQ(22) /* FFUART Transmit/Receive/Error*/ | 52 | #define IRQ_FFUART PXA_IRQ(22) /* FFUART Transmit/Receive/Error*/ |
@@ -60,19 +60,17 @@ | |||
60 | #define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */ | 60 | #define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */ |
61 | #define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */ | 61 | #define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */ |
62 | 62 | ||
63 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
64 | #define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */ | 63 | #define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */ |
65 | #define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */ | 64 | #define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */ |
66 | #endif | ||
67 | |||
68 | #ifdef CONFIG_PXA3xx | ||
69 | #define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request */ | ||
70 | #define IRQ_CIR PXA_IRQ(34) /* Consumer IR */ | 65 | #define IRQ_CIR PXA_IRQ(34) /* Consumer IR */ |
71 | #define IRQ_COMM_WDT PXA_IRQ(35) /* Comm WDT interrupt */ | 66 | #define IRQ_COMM_WDT PXA_IRQ(35) /* Comm WDT interrupt */ |
72 | #define IRQ_TSI PXA_IRQ(36) /* Touch Screen Interface (PXA320) */ | 67 | #define IRQ_TSI PXA_IRQ(36) /* Touch Screen Interface (PXA320) */ |
68 | #define IRQ_ENHROT PXA_IRQ(37) /* Enhanced Rotary (PXA930) */ | ||
73 | #define IRQ_USIM2 PXA_IRQ(38) /* USIM2 Controller */ | 69 | #define IRQ_USIM2 PXA_IRQ(38) /* USIM2 Controller */ |
74 | #define IRQ_GCU PXA_IRQ(39) /* Graphics Controller */ | 70 | #define IRQ_GCU PXA_IRQ(39) /* Graphics Controller (PXA3xx) */ |
71 | #define IRQ_ACIPC1 PXA_IRQ(40) /* AP-CP Communication (PXA930) */ | ||
75 | #define IRQ_MMC2 PXA_IRQ(41) /* MMC2 Controller */ | 72 | #define IRQ_MMC2 PXA_IRQ(41) /* MMC2 Controller */ |
73 | #define IRQ_TRKBALL PXA_IRQ(43) /* Track Ball (PXA930) */ | ||
76 | #define IRQ_1WIRE PXA_IRQ(44) /* 1-Wire Controller */ | 74 | #define IRQ_1WIRE PXA_IRQ(44) /* 1-Wire Controller */ |
77 | #define IRQ_NAND PXA_IRQ(45) /* NAND Controller */ | 75 | #define IRQ_NAND PXA_IRQ(45) /* NAND Controller */ |
78 | #define IRQ_USB2 PXA_IRQ(46) /* USB 2.0 Device Controller */ | 76 | #define IRQ_USB2 PXA_IRQ(46) /* USB 2.0 Device Controller */ |
@@ -80,30 +78,14 @@ | |||
80 | #define IRQ_WAKEUP1 PXA_IRQ(50) /* EXT_WAKEUP1 */ | 78 | #define IRQ_WAKEUP1 PXA_IRQ(50) /* EXT_WAKEUP1 */ |
81 | #define IRQ_DMEMC PXA_IRQ(51) /* Dynamic Memory Controller */ | 79 | #define IRQ_DMEMC PXA_IRQ(51) /* Dynamic Memory Controller */ |
82 | #define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */ | 80 | #define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */ |
83 | #endif | ||
84 | 81 | ||
85 | #ifdef CONFIG_CPU_PXA935 | ||
86 | #define IRQ_U2O PXA_IRQ(64) /* USB OTG 2.0 Controller (PXA935) */ | 82 | #define IRQ_U2O PXA_IRQ(64) /* USB OTG 2.0 Controller (PXA935) */ |
87 | #define IRQ_U2H PXA_IRQ(65) /* USB Host 2.0 Controller (PXA935) */ | 83 | #define IRQ_U2H PXA_IRQ(65) /* USB Host 2.0 Controller (PXA935) */ |
88 | 84 | #define IRQ_PXA935_MMC0 PXA_IRQ(72) /* MMC0 Controller (PXA935) */ | |
89 | #define IRQ_MMC3_PXA935 PXA_IRQ(72) /* MMC3 Controller (PXA935) */ | 85 | #define IRQ_PXA935_MMC1 PXA_IRQ(73) /* MMC1 Controller (PXA935) */ |
90 | #define IRQ_MMC4_PXA935 PXA_IRQ(73) /* MMC4 Controller (PXA935) */ | 86 | #define IRQ_PXA935_MMC2 PXA_IRQ(74) /* MMC2 Controller (PXA935) */ |
91 | #define IRQ_MMC5_PXA935 PXA_IRQ(74) /* MMC5 Controller (PXA935) */ | 87 | #define IRQ_PXA955_MMC3 PXA_IRQ(75) /* MMC3 Controller (PXA955) */ |
92 | |||
93 | #define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */ | 88 | #define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */ |
94 | #endif | ||
95 | |||
96 | #ifdef CONFIG_CPU_PXA930 | ||
97 | #define IRQ_ENHROT PXA_IRQ(37) /* Enhanced Rotary (PXA930) */ | ||
98 | #define IRQ_ACIPC0 PXA_IRQ(5) | ||
99 | #define IRQ_ACIPC1 PXA_IRQ(40) | ||
100 | #define IRQ_ACIPC2 PXA_IRQ(19) | ||
101 | #define IRQ_TRKBALL PXA_IRQ(43) /* Track Ball */ | ||
102 | #endif | ||
103 | |||
104 | #ifdef CONFIG_CPU_PXA950 | ||
105 | #define IRQ_GC500 PXA_IRQ(70) /* Graphics Controller (PXA950) */ | ||
106 | #endif | ||
107 | 89 | ||
108 | #define PXA_GPIO_IRQ_BASE PXA_IRQ(96) | 90 | #define PXA_GPIO_IRQ_BASE PXA_IRQ(96) |
109 | #define PXA_GPIO_IRQ_NUM (192) | 91 | #define PXA_GPIO_IRQ_NUM (192) |
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h index 4fcddd9cab76..ee6ced1cea7f 100644 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h | |||
@@ -17,72 +17,6 @@ | |||
17 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
18 | 18 | ||
19 | /* | 19 | /* |
20 | * PXA Chip selects | ||
21 | */ | ||
22 | |||
23 | #define PXA_CS0_PHYS 0x00000000 | ||
24 | #define PXA_CS1_PHYS 0x04000000 | ||
25 | #define PXA_CS2_PHYS 0x08000000 | ||
26 | #define PXA_CS3_PHYS 0x0C000000 | ||
27 | #define PXA_CS4_PHYS 0x10000000 | ||
28 | #define PXA_CS5_PHYS 0x14000000 | ||
29 | |||
30 | /* | ||
31 | * Memory controller | ||
32 | */ | ||
33 | |||
34 | #define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */ | ||
35 | #define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */ | ||
36 | #define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */ | ||
37 | #define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */ | ||
38 | #define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */ | ||
39 | #define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ | ||
40 | #define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ | ||
41 | #define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */ | ||
42 | #define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */ | ||
43 | #define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */ | ||
44 | #define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */ | ||
45 | #define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */ | ||
46 | #define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */ | ||
47 | #define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */ | ||
48 | #define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */ | ||
49 | #define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */ | ||
50 | #define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ | ||
51 | |||
52 | /* | ||
53 | * More handy macros for PCMCIA | ||
54 | * | ||
55 | * Arg is socket number | ||
56 | */ | ||
57 | #define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */ | ||
58 | #define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */ | ||
59 | #define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */ | ||
60 | |||
61 | /* MECR register defines */ | ||
62 | #define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ | ||
63 | #define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ | ||
64 | |||
65 | #define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */ | ||
66 | #define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */ | ||
67 | #define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */ | ||
68 | #define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */ | ||
69 | |||
70 | #define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */ | ||
71 | #define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ | ||
72 | #define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ | ||
73 | #define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ | ||
74 | #define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ | ||
75 | #define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ | ||
76 | #define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ | ||
77 | #define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ | ||
78 | #define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ | ||
79 | #define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ | ||
80 | #define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ | ||
81 | #define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ | ||
82 | #define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ | ||
83 | #define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ | ||
84 | |||
85 | /* | ||
86 | * Power Manager | 20 | * Power Manager |
87 | */ | 21 | */ |
88 | 22 | ||
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h index e91d63cfe811..e4fb4668c26e 100644 --- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h | |||
@@ -16,15 +16,6 @@ | |||
16 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Static Chip Selects | ||
20 | */ | ||
21 | |||
22 | #define PXA300_CS0_PHYS (0x00000000) /* PXA300/PXA310 _only_ */ | ||
23 | #define PXA300_CS1_PHYS (0x30000000) /* PXA300/PXA310 _only_ */ | ||
24 | #define PXA3xx_CS2_PHYS (0x10000000) | ||
25 | #define PXA3xx_CS3_PHYS (0x14000000) | ||
26 | |||
27 | /* | ||
28 | * Oscillator Configuration Register (OSCC) | 19 | * Oscillator Configuration Register (OSCC) |
29 | */ | 20 | */ |
30 | #define OSCC __REG(0x41350000) /* Oscillator Configuration Register */ | 21 | #define OSCC __REG(0x41350000) /* Oscillator Configuration Register */ |
diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h b/arch/arm/mach-pxa/include/mach/regs-intc.h index 68464ce1c1ea..662288eb6f95 100644 --- a/arch/arm/mach-pxa/include/mach/regs-intc.h +++ b/arch/arm/mach-pxa/include/mach/regs-intc.h | |||
@@ -27,8 +27,4 @@ | |||
27 | #define ICFP3 __REG(0x40D0013C) /* Interrupt Controller FIQ Pending Register 3 */ | 27 | #define ICFP3 __REG(0x40D0013C) /* Interrupt Controller FIQ Pending Register 3 */ |
28 | #define ICPR3 __REG(0x40D00140) /* Interrupt Controller Pending Register 3 */ | 28 | #define ICPR3 __REG(0x40D00140) /* Interrupt Controller Pending Register 3 */ |
29 | 29 | ||
30 | #define IPR(x) __REG(0x40D0001C + (x < 32 ? (x << 2) \ | ||
31 | : (x < 64 ? (0x94 + ((x - 32) << 2)) \ | ||
32 | : (0x128 + ((x - 64) << 2))))) | ||
33 | |||
34 | #endif /* __ASM_MACH_REGS_INTC_H */ | 30 | #endif /* __ASM_MACH_REGS_INTC_H */ |
diff --git a/arch/arm/mach-pxa/include/mach/smemc.h b/arch/arm/mach-pxa/include/mach/smemc.h new file mode 100644 index 000000000000..654adc90c9a0 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/smemc.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Static memory controller register definitions for PXA CPUs | ||
3 | * | ||
4 | * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __SMEMC_REGS_H | ||
12 | #define __SMEMC_REGS_H | ||
13 | |||
14 | #define PXA2XX_SMEMC_BASE 0x48000000 | ||
15 | #define PXA3XX_SMEMC_BASE 0x4a000000 | ||
16 | #define SMEMC_VIRT 0xf6000000 | ||
17 | |||
18 | #define MDCNFG (SMEMC_VIRT + 0x00) /* SDRAM Configuration Register 0 */ | ||
19 | #define MDREFR (SMEMC_VIRT + 0x04) /* SDRAM Refresh Control Register */ | ||
20 | #define MSC0 (SMEMC_VIRT + 0x08) /* Static Memory Control Register 0 */ | ||
21 | #define MSC1 (SMEMC_VIRT + 0x0C) /* Static Memory Control Register 1 */ | ||
22 | #define MSC2 (SMEMC_VIRT + 0x10) /* Static Memory Control Register 2 */ | ||
23 | #define MECR (SMEMC_VIRT + 0x14) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */ | ||
24 | #define SXLCR (SMEMC_VIRT + 0x18) /* LCR value to be written to SDRAM-Timing Synchronous Flash */ | ||
25 | #define SXCNFG (SMEMC_VIRT + 0x1C) /* Synchronous Static Memory Control Register */ | ||
26 | #define SXMRS (SMEMC_VIRT + 0x24) /* MRS value to be written to Synchronous Flash or SMROM */ | ||
27 | #define MCMEM0 (SMEMC_VIRT + 0x28) /* Card interface Common Memory Space Socket 0 Timing */ | ||
28 | #define MCMEM1 (SMEMC_VIRT + 0x2C) /* Card interface Common Memory Space Socket 1 Timing */ | ||
29 | #define MCATT0 (SMEMC_VIRT + 0x30) /* Card interface Attribute Space Socket 0 Timing Configuration */ | ||
30 | #define MCATT1 (SMEMC_VIRT + 0x34) /* Card interface Attribute Space Socket 1 Timing Configuration */ | ||
31 | #define MCIO0 (SMEMC_VIRT + 0x38) /* Card interface I/O Space Socket 0 Timing Configuration */ | ||
32 | #define MCIO1 (SMEMC_VIRT + 0x3C) /* Card interface I/O Space Socket 1 Timing Configuration */ | ||
33 | #define MDMRS (SMEMC_VIRT + 0x40) /* MRS value to be written to SDRAM */ | ||
34 | #define BOOT_DEF (SMEMC_VIRT + 0x44) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */ | ||
35 | #define MEMCLKCFG (SMEMC_VIRT + 0x68) /* Clock Configuration */ | ||
36 | #define CSADRCFG0 (SMEMC_VIRT + 0x80) /* Address Configuration Register for CS0 */ | ||
37 | #define CSADRCFG1 (SMEMC_VIRT + 0x84) /* Address Configuration Register for CS1 */ | ||
38 | #define CSADRCFG2 (SMEMC_VIRT + 0x88) /* Address Configuration Register for CS2 */ | ||
39 | #define CSADRCFG3 (SMEMC_VIRT + 0x8C) /* Address Configuration Register for CS3 */ | ||
40 | |||
41 | /* | ||
42 | * More handy macros for PCMCIA | ||
43 | * | ||
44 | * Arg is socket number | ||
45 | */ | ||
46 | #define MCMEM(s) (SMEMC_VIRT + 0x28 + ((s)<<2)) /* Card interface Common Memory Space Socket s Timing */ | ||
47 | #define MCATT(s) (SMEMC_VIRT + 0x30 + ((s)<<2)) /* Card interface Attribute Space Socket s Timing Configuration */ | ||
48 | #define MCIO(s) (SMEMC_VIRT + 0x38 + ((s)<<2)) /* Card interface I/O Space Socket s Timing Configuration */ | ||
49 | |||
50 | /* MECR register defines */ | ||
51 | #define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ | ||
52 | #define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ | ||
53 | |||
54 | #define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */ | ||
55 | #define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */ | ||
56 | #define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */ | ||
57 | #define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */ | ||
58 | |||
59 | #define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */ | ||
60 | #define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ | ||
61 | #define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ | ||
62 | #define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ | ||
63 | #define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */ | ||
64 | #define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */ | ||
65 | #define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */ | ||
66 | #define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */ | ||
67 | #define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */ | ||
68 | #define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */ | ||
69 | #define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */ | ||
70 | #define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */ | ||
71 | #define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */ | ||
72 | #define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */ | ||
73 | |||
74 | #endif | ||
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 1beb40f692fc..54e91c9e71c8 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c | |||
@@ -16,20 +16,31 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/sysdev.h> | 18 | #include <linux/sysdev.h> |
19 | #include <linux/io.h> | ||
20 | #include <linux/irq.h> | ||
19 | 21 | ||
20 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
21 | #include <asm/irq.h> | 23 | #include <mach/irqs.h> |
22 | #include <asm/mach/irq.h> | ||
23 | #include <mach/gpio.h> | 24 | #include <mach/gpio.h> |
24 | #include <mach/regs-intc.h> | ||
25 | 25 | ||
26 | #include "generic.h" | 26 | #include "generic.h" |
27 | 27 | ||
28 | #define MAX_INTERNAL_IRQS 128 | 28 | #define IRQ_BASE (void __iomem *)io_p2v(0x40d00000) |
29 | |||
30 | #define ICIP (0x000) | ||
31 | #define ICMR (0x004) | ||
32 | #define ICLR (0x008) | ||
33 | #define ICFR (0x00c) | ||
34 | #define ICPR (0x010) | ||
35 | #define ICCR (0x014) | ||
36 | #define ICHP (0x018) | ||
37 | #define IPR(i) (((i) < 32) ? (0x01c + ((i) << 2)) : \ | ||
38 | ((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) : \ | ||
39 | (0x144 + (((i) - 64) << 2))) | ||
40 | #define IPR_VALID (1 << 31) | ||
41 | #define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f) | ||
29 | 42 | ||
30 | #define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f) | 43 | #define MAX_INTERNAL_IRQS 128 |
31 | #define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR)) | ||
32 | #define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR)) | ||
33 | 44 | ||
34 | /* | 45 | /* |
35 | * This is for peripheral IRQs internal to the PXA chip. | 46 | * This is for peripheral IRQs internal to the PXA chip. |
@@ -37,14 +48,27 @@ | |||
37 | 48 | ||
38 | static int pxa_internal_irq_nr; | 49 | static int pxa_internal_irq_nr; |
39 | 50 | ||
51 | static inline int cpu_has_ipr(void) | ||
52 | { | ||
53 | return !cpu_is_pxa25x(); | ||
54 | } | ||
55 | |||
40 | static void pxa_mask_irq(unsigned int irq) | 56 | static void pxa_mask_irq(unsigned int irq) |
41 | { | 57 | { |
42 | _ICMR(irq) &= ~(1 << IRQ_BIT(irq)); | 58 | void __iomem *base = get_irq_chip_data(irq); |
59 | uint32_t icmr = __raw_readl(base + ICMR); | ||
60 | |||
61 | icmr &= ~(1 << IRQ_BIT(irq)); | ||
62 | __raw_writel(icmr, base + ICMR); | ||
43 | } | 63 | } |
44 | 64 | ||
45 | static void pxa_unmask_irq(unsigned int irq) | 65 | static void pxa_unmask_irq(unsigned int irq) |
46 | { | 66 | { |
47 | _ICMR(irq) |= 1 << IRQ_BIT(irq); | 67 | void __iomem *base = get_irq_chip_data(irq); |
68 | uint32_t icmr = __raw_readl(base + ICMR); | ||
69 | |||
70 | icmr |= 1 << IRQ_BIT(irq); | ||
71 | __raw_writel(icmr, base + ICMR); | ||
48 | } | 72 | } |
49 | 73 | ||
50 | static struct irq_chip pxa_internal_irq_chip = { | 74 | static struct irq_chip pxa_internal_irq_chip = { |
@@ -86,12 +110,16 @@ static void pxa_ack_low_gpio(unsigned int irq) | |||
86 | 110 | ||
87 | static void pxa_mask_low_gpio(unsigned int irq) | 111 | static void pxa_mask_low_gpio(unsigned int irq) |
88 | { | 112 | { |
89 | ICMR &= ~(1 << (irq - PXA_IRQ(0))); | 113 | struct irq_desc *desc = irq_to_desc(irq); |
114 | |||
115 | desc->chip->mask(irq); | ||
90 | } | 116 | } |
91 | 117 | ||
92 | static void pxa_unmask_low_gpio(unsigned int irq) | 118 | static void pxa_unmask_low_gpio(unsigned int irq) |
93 | { | 119 | { |
94 | ICMR |= 1 << (irq - PXA_IRQ(0)); | 120 | struct irq_desc *desc = irq_to_desc(irq); |
121 | |||
122 | desc->chip->unmask(irq); | ||
95 | } | 123 | } |
96 | 124 | ||
97 | static struct irq_chip pxa_low_gpio_chip = { | 125 | static struct irq_chip pxa_low_gpio_chip = { |
@@ -120,33 +148,45 @@ static void __init pxa_init_low_gpio_irq(set_wake_t fn) | |||
120 | pxa_low_gpio_chip.set_wake = fn; | 148 | pxa_low_gpio_chip.set_wake = fn; |
121 | } | 149 | } |
122 | 150 | ||
151 | static inline void __iomem *irq_base(int i) | ||
152 | { | ||
153 | static unsigned long phys_base[] = { | ||
154 | 0x40d00000, | ||
155 | 0x40d0009c, | ||
156 | 0x40d00130, | ||
157 | }; | ||
158 | |||
159 | return (void __iomem *)io_p2v(phys_base[i >> 5]); | ||
160 | } | ||
161 | |||
123 | void __init pxa_init_irq(int irq_nr, set_wake_t fn) | 162 | void __init pxa_init_irq(int irq_nr, set_wake_t fn) |
124 | { | 163 | { |
125 | int irq, i; | 164 | int irq, i, n; |
126 | 165 | ||
127 | BUG_ON(irq_nr > MAX_INTERNAL_IRQS); | 166 | BUG_ON(irq_nr > MAX_INTERNAL_IRQS); |
128 | 167 | ||
129 | pxa_internal_irq_nr = irq_nr; | 168 | pxa_internal_irq_nr = irq_nr; |
130 | 169 | ||
131 | for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) { | 170 | for (n = 0; n < irq_nr; n += 32) { |
132 | _ICMR(irq) = 0; /* disable all IRQs */ | 171 | void __iomem *base = irq_base(n); |
133 | _ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */ | 172 | |
134 | } | 173 | __raw_writel(0, base + ICMR); /* disable all IRQs */ |
135 | 174 | __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */ | |
136 | /* initialize interrupt priority */ | 175 | for (i = n; (i < (n + 32)) && (i < irq_nr); i++) { |
137 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) { | 176 | /* initialize interrupt priority */ |
138 | for (i = 0; i < irq_nr; i++) | 177 | if (cpu_has_ipr()) |
139 | IPR(i) = i | (1 << 31); | 178 | __raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i)); |
179 | |||
180 | irq = PXA_IRQ(i); | ||
181 | set_irq_chip(irq, &pxa_internal_irq_chip); | ||
182 | set_irq_chip_data(irq, base); | ||
183 | set_irq_handler(irq, handle_level_irq); | ||
184 | set_irq_flags(irq, IRQF_VALID); | ||
185 | } | ||
140 | } | 186 | } |
141 | 187 | ||
142 | /* only unmasked interrupts kick us out of idle */ | 188 | /* only unmasked interrupts kick us out of idle */ |
143 | ICCR = 1; | 189 | __raw_writel(1, irq_base(0) + ICCR); |
144 | |||
145 | for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) { | ||
146 | set_irq_chip(irq, &pxa_internal_irq_chip); | ||
147 | set_irq_handler(irq, handle_level_irq); | ||
148 | set_irq_flags(irq, IRQF_VALID); | ||
149 | } | ||
150 | 190 | ||
151 | pxa_internal_irq_chip.set_wake = fn; | 191 | pxa_internal_irq_chip.set_wake = fn; |
152 | pxa_init_low_gpio_irq(fn); | 192 | pxa_init_low_gpio_irq(fn); |
@@ -158,16 +198,18 @@ static unsigned long saved_ipr[MAX_INTERNAL_IRQS]; | |||
158 | 198 | ||
159 | static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) | 199 | static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) |
160 | { | 200 | { |
161 | int i, irq = PXA_IRQ(0); | 201 | int i; |
162 | 202 | ||
163 | for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { | 203 | for (i = 0; i < pxa_internal_irq_nr; i += 32) { |
164 | saved_icmr[i] = _ICMR(irq); | 204 | void __iomem *base = irq_base(i); |
165 | _ICMR(irq) = 0; | 205 | |
206 | saved_icmr[i] = __raw_readl(base + ICMR); | ||
207 | __raw_writel(0, base + ICMR); | ||
166 | } | 208 | } |
167 | 209 | ||
168 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) { | 210 | if (cpu_has_ipr()) { |
169 | for (i = 0; i < pxa_internal_irq_nr; i++) | 211 | for (i = 0; i < pxa_internal_irq_nr; i++) |
170 | saved_ipr[i] = IPR(i); | 212 | saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i)); |
171 | } | 213 | } |
172 | 214 | ||
173 | return 0; | 215 | return 0; |
@@ -175,19 +217,20 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) | |||
175 | 217 | ||
176 | static int pxa_irq_resume(struct sys_device *dev) | 218 | static int pxa_irq_resume(struct sys_device *dev) |
177 | { | 219 | { |
178 | int i, irq = PXA_IRQ(0); | 220 | int i; |
179 | 221 | ||
180 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) { | 222 | for (i = 0; i < pxa_internal_irq_nr; i += 32) { |
181 | for (i = 0; i < pxa_internal_irq_nr; i++) | 223 | void __iomem *base = irq_base(i); |
182 | IPR(i) = saved_ipr[i]; | ||
183 | } | ||
184 | 224 | ||
185 | for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { | 225 | __raw_writel(saved_icmr[i], base + ICMR); |
186 | _ICMR(irq) = saved_icmr[i]; | 226 | __raw_writel(0, base + ICLR); |
187 | _ICLR(irq) = 0; | ||
188 | } | 227 | } |
189 | 228 | ||
190 | ICCR = 1; | 229 | if (!cpu_is_pxa25x()) |
230 | for (i = 0; i < pxa_internal_irq_nr; i++) | ||
231 | __raw_writel(saved_ipr[i], IRQ_BASE + IPR(i)); | ||
232 | |||
233 | __raw_writel(1, IRQ_BASE + ICCR); | ||
191 | return 0; | 234 | return 0; |
192 | } | 235 | } |
193 | #else | 236 | #else |
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 41aa89e35772..719c260597e7 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c | |||
@@ -438,7 +438,7 @@ static void __init littleton_init(void) | |||
438 | 438 | ||
439 | MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)") | 439 | MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)") |
440 | .boot_params = 0xa0000100, | 440 | .boot_params = 0xa0000100, |
441 | .map_io = pxa_map_io, | 441 | .map_io = pxa3xx_map_io, |
442 | .nr_irqs = LITTLETON_NR_IRQS, | 442 | .nr_irqs = LITTLETON_NR_IRQS, |
443 | .init_irq = pxa3xx_init_irq, | 443 | .init_irq = pxa3xx_init_irq, |
444 | .timer = &pxa_timer, | 444 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 623af0232a54..8ab62a677807 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <mach/mmc.h> | 46 | #include <mach/mmc.h> |
47 | #include <mach/irda.h> | 47 | #include <mach/irda.h> |
48 | #include <mach/ohci.h> | 48 | #include <mach/ohci.h> |
49 | #include <mach/smemc.h> | ||
49 | 50 | ||
50 | #include "generic.h" | 51 | #include "generic.h" |
51 | #include "devices.h" | 52 | #include "devices.h" |
@@ -463,7 +464,7 @@ static void __init lpd270_init(void) | |||
463 | pxa_set_btuart_info(NULL); | 464 | pxa_set_btuart_info(NULL); |
464 | pxa_set_stuart_info(NULL); | 465 | pxa_set_stuart_info(NULL); |
465 | 466 | ||
466 | lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4; | 467 | lpd270_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4; |
467 | lpd270_flash_data[1].width = 4; | 468 | lpd270_flash_data[1].width = 4; |
468 | 469 | ||
469 | /* | 470 | /* |
@@ -495,7 +496,7 @@ static struct map_desc lpd270_io_desc[] __initdata = { | |||
495 | 496 | ||
496 | static void __init lpd270_map_io(void) | 497 | static void __init lpd270_map_io(void) |
497 | { | 498 | { |
498 | pxa_map_io(); | 499 | pxa27x_map_io(); |
499 | iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc)); | 500 | iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc)); |
500 | 501 | ||
501 | /* for use I SRAM as framebuffer. */ | 502 | /* for use I SRAM as framebuffer. */ |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 1499493cd070..d3375486c8cd 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <mach/pxafb.h> | 50 | #include <mach/pxafb.h> |
51 | #include <mach/mmc.h> | 51 | #include <mach/mmc.h> |
52 | #include <mach/pm.h> | 52 | #include <mach/pm.h> |
53 | #include <mach/smemc.h> | ||
53 | 54 | ||
54 | #include "generic.h" | 55 | #include "generic.h" |
55 | #include "clock.h" | 56 | #include "clock.h" |
@@ -525,7 +526,7 @@ static void __init lubbock_init(void) | |||
525 | pxa_set_ac97_info(NULL); | 526 | pxa_set_ac97_info(NULL); |
526 | 527 | ||
527 | lubbock_flash_data[0].width = lubbock_flash_data[1].width = | 528 | lubbock_flash_data[0].width = lubbock_flash_data[1].width = |
528 | (BOOT_DEF & 1) ? 2 : 4; | 529 | (__raw_readl(BOOT_DEF) & 1) ? 2 : 4; |
529 | /* Compensate for the nROMBT switch which swaps the flash banks */ | 530 | /* Compensate for the nROMBT switch which swaps the flash banks */ |
530 | printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", | 531 | printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", |
531 | flashboot?"Flash":"ROM", flashboot); | 532 | flashboot?"Flash":"ROM", flashboot); |
@@ -549,7 +550,7 @@ static struct map_desc lubbock_io_desc[] __initdata = { | |||
549 | 550 | ||
550 | static void __init lubbock_map_io(void) | 551 | static void __init lubbock_map_io(void) |
551 | { | 552 | { |
552 | pxa_map_io(); | 553 | pxa25x_map_io(); |
553 | iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc)); | 554 | iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc)); |
554 | 555 | ||
555 | PCFR |= PCFR_OPDE; | 556 | PCFR |= PCFR_OPDE; |
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 90663760307a..41198f0dc3ac 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c | |||
@@ -765,7 +765,7 @@ static void __init magician_init(void) | |||
765 | 765 | ||
766 | MACHINE_START(MAGICIAN, "HTC Magician") | 766 | MACHINE_START(MAGICIAN, "HTC Magician") |
767 | .boot_params = 0xa0000100, | 767 | .boot_params = 0xa0000100, |
768 | .map_io = pxa_map_io, | 768 | .map_io = pxa27x_map_io, |
769 | .nr_irqs = MAGICIAN_NR_IRQS, | 769 | .nr_irqs = MAGICIAN_NR_IRQS, |
770 | .init_irq = pxa27x_init_irq, | 770 | .init_irq = pxa27x_init_irq, |
771 | .init_machine = magician_init, | 771 | .init_machine = magician_init, |
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index a980a5c93e49..740c03590e3b 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <mach/irda.h> | 51 | #include <mach/irda.h> |
52 | #include <mach/ohci.h> | 52 | #include <mach/ohci.h> |
53 | #include <plat/pxa27x_keypad.h> | 53 | #include <plat/pxa27x_keypad.h> |
54 | #include <mach/smemc.h> | ||
54 | 55 | ||
55 | #include "generic.h" | 56 | #include "generic.h" |
56 | #include "devices.h" | 57 | #include "devices.h" |
@@ -565,7 +566,7 @@ static void __init mainstone_init(void) | |||
565 | pxa_set_btuart_info(NULL); | 566 | pxa_set_btuart_info(NULL); |
566 | pxa_set_stuart_info(NULL); | 567 | pxa_set_stuart_info(NULL); |
567 | 568 | ||
568 | mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4; | 569 | mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4; |
569 | mst_flash_data[1].width = 4; | 570 | mst_flash_data[1].width = 4; |
570 | 571 | ||
571 | /* Compensate for SW7 which swaps the flash banks */ | 572 | /* Compensate for SW7 which swaps the flash banks */ |
@@ -614,7 +615,7 @@ static struct map_desc mainstone_io_desc[] __initdata = { | |||
614 | 615 | ||
615 | static void __init mainstone_map_io(void) | 616 | static void __init mainstone_map_io(void) |
616 | { | 617 | { |
617 | pxa_map_io(); | 618 | pxa27x_map_io(); |
618 | iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc)); | 619 | iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc)); |
619 | 620 | ||
620 | /* for use I SRAM as framebuffer. */ | 621 | /* for use I SRAM as framebuffer. */ |
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index f5fb915e1315..faafea3542fb 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c | |||
@@ -819,7 +819,7 @@ static void mioa701_machine_exit(void) | |||
819 | 819 | ||
820 | MACHINE_START(MIOA701, "MIO A701") | 820 | MACHINE_START(MIOA701, "MIO A701") |
821 | .boot_params = 0xa0000100, | 821 | .boot_params = 0xa0000100, |
822 | .map_io = &pxa_map_io, | 822 | .map_io = &pxa27x_map_io, |
823 | .init_irq = &pxa27x_init_irq, | 823 | .init_irq = &pxa27x_init_irq, |
824 | .init_machine = mioa701_machine_init, | 824 | .init_machine = mioa701_machine_init, |
825 | .timer = &pxa_timer, | 825 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c index 116167aaba68..59cce78aebd1 100644 --- a/arch/arm/mach-pxa/mp900.c +++ b/arch/arm/mach-pxa/mp900.c | |||
@@ -94,7 +94,7 @@ static void __init mp900c_init(void) | |||
94 | MACHINE_START(NEC_MP900, "MobilePro900/C") | 94 | MACHINE_START(NEC_MP900, "MobilePro900/C") |
95 | .boot_params = 0xa0220100, | 95 | .boot_params = 0xa0220100, |
96 | .timer = &pxa_timer, | 96 | .timer = &pxa_timer, |
97 | .map_io = pxa_map_io, | 97 | .map_io = pxa25x_map_io, |
98 | .init_irq = pxa25x_init_irq, | 98 | .init_irq = pxa25x_init_irq, |
99 | .init_machine = mp900c_init, | 99 | .init_machine = mp900c_init, |
100 | MACHINE_END | 100 | MACHINE_END |
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index ce092c521e6d..a6f898cbfac9 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c | |||
@@ -313,7 +313,7 @@ static struct map_desc palmld_io_desc[] __initdata = { | |||
313 | 313 | ||
314 | static void __init palmld_map_io(void) | 314 | static void __init palmld_map_io(void) |
315 | { | 315 | { |
316 | pxa_map_io(); | 316 | pxa27x_map_io(); |
317 | iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc)); | 317 | iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc)); |
318 | } | 318 | } |
319 | 319 | ||
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 862da812cd10..df4d7d009fbb 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c | |||
@@ -203,7 +203,7 @@ static void __init palmt5_init(void) | |||
203 | 203 | ||
204 | MACHINE_START(PALMT5, "Palm Tungsten|T5") | 204 | MACHINE_START(PALMT5, "Palm Tungsten|T5") |
205 | .boot_params = 0xa0000100, | 205 | .boot_params = 0xa0000100, |
206 | .map_io = pxa_map_io, | 206 | .map_io = pxa27x_map_io, |
207 | .reserve = palmt5_reserve, | 207 | .reserve = palmt5_reserve, |
208 | .init_irq = pxa27x_init_irq, | 208 | .init_irq = pxa27x_init_irq, |
209 | .timer = &pxa_timer, | 209 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 2131d5860919..a09a2374697b 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/power_supply.h> | 25 | #include <linux/power_supply.h> |
26 | #include <linux/gpio_keys.h> | 26 | #include <linux/gpio_keys.h> |
27 | #include <linux/mtd/physmap.h> | 27 | #include <linux/mtd/physmap.h> |
28 | #include <linux/usb/gpio_vbus.h> | ||
28 | 29 | ||
29 | #include <asm/mach-types.h> | 30 | #include <asm/mach-types.h> |
30 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
@@ -116,6 +117,7 @@ static unsigned long palmtc_pin_config[] __initdata = { | |||
116 | /****************************************************************************** | 117 | /****************************************************************************** |
117 | * SD/MMC card controller | 118 | * SD/MMC card controller |
118 | ******************************************************************************/ | 119 | ******************************************************************************/ |
120 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) | ||
119 | static struct pxamci_platform_data palmtc_mci_platform_data = { | 121 | static struct pxamci_platform_data palmtc_mci_platform_data = { |
120 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 122 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
121 | .gpio_power = GPIO_NR_PALMTC_SD_POWER, | 123 | .gpio_power = GPIO_NR_PALMTC_SD_POWER, |
@@ -124,9 +126,18 @@ static struct pxamci_platform_data palmtc_mci_platform_data = { | |||
124 | .detect_delay_ms = 200, | 126 | .detect_delay_ms = 200, |
125 | }; | 127 | }; |
126 | 128 | ||
129 | static void __init palmtc_mmc_init(void) | ||
130 | { | ||
131 | pxa_set_mci_info(&palmtc_mci_platform_data); | ||
132 | } | ||
133 | #else | ||
134 | static inline void palmtc_mmc_init(void) {} | ||
135 | #endif | ||
136 | |||
127 | /****************************************************************************** | 137 | /****************************************************************************** |
128 | * GPIO keys | 138 | * GPIO keys |
129 | ******************************************************************************/ | 139 | ******************************************************************************/ |
140 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
130 | static struct gpio_keys_button palmtc_pxa_buttons[] = { | 141 | static struct gpio_keys_button palmtc_pxa_buttons[] = { |
131 | {KEY_F8, GPIO_NR_PALMTC_HOTSYNC_BUTTON, 1, "HotSync Button", EV_KEY, 1}, | 142 | {KEY_F8, GPIO_NR_PALMTC_HOTSYNC_BUTTON, 1, "HotSync Button", EV_KEY, 1}, |
132 | }; | 143 | }; |
@@ -144,9 +155,18 @@ static struct platform_device palmtc_pxa_keys = { | |||
144 | }, | 155 | }, |
145 | }; | 156 | }; |
146 | 157 | ||
158 | static void __init palmtc_keys_init(void) | ||
159 | { | ||
160 | platform_device_register(&palmtc_pxa_keys); | ||
161 | } | ||
162 | #else | ||
163 | static inline void palmtc_keys_init(void) {} | ||
164 | #endif | ||
165 | |||
147 | /****************************************************************************** | 166 | /****************************************************************************** |
148 | * Backlight | 167 | * Backlight |
149 | ******************************************************************************/ | 168 | ******************************************************************************/ |
169 | #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) | ||
150 | static int palmtc_backlight_init(struct device *dev) | 170 | static int palmtc_backlight_init(struct device *dev) |
151 | { | 171 | { |
152 | int ret; | 172 | int ret; |
@@ -196,17 +216,35 @@ static struct platform_device palmtc_backlight = { | |||
196 | }, | 216 | }, |
197 | }; | 217 | }; |
198 | 218 | ||
219 | static void __init palmtc_pwm_init(void) | ||
220 | { | ||
221 | platform_device_register(&palmtc_backlight); | ||
222 | } | ||
223 | #else | ||
224 | static inline void palmtc_pwm_init(void) {} | ||
225 | #endif | ||
226 | |||
199 | /****************************************************************************** | 227 | /****************************************************************************** |
200 | * IrDA | 228 | * IrDA |
201 | ******************************************************************************/ | 229 | ******************************************************************************/ |
230 | #if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) | ||
202 | static struct pxaficp_platform_data palmtc_ficp_platform_data = { | 231 | static struct pxaficp_platform_data palmtc_ficp_platform_data = { |
203 | .gpio_pwdown = GPIO_NR_PALMTC_IR_DISABLE, | 232 | .gpio_pwdown = GPIO_NR_PALMTC_IR_DISABLE, |
204 | .transceiver_cap = IR_SIRMODE | IR_OFF, | 233 | .transceiver_cap = IR_SIRMODE | IR_OFF, |
205 | }; | 234 | }; |
206 | 235 | ||
236 | static void __init palmtc_irda_init(void) | ||
237 | { | ||
238 | pxa_set_ficp_info(&palmtc_ficp_platform_data); | ||
239 | } | ||
240 | #else | ||
241 | static inline void palmtc_irda_init(void) {} | ||
242 | #endif | ||
243 | |||
207 | /****************************************************************************** | 244 | /****************************************************************************** |
208 | * Keyboard | 245 | * Keyboard |
209 | ******************************************************************************/ | 246 | ******************************************************************************/ |
247 | #if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE) | ||
210 | static const uint32_t palmtc_matrix_keys[] = { | 248 | static const uint32_t palmtc_matrix_keys[] = { |
211 | KEY(0, 0, KEY_F1), | 249 | KEY(0, 0, KEY_F1), |
212 | KEY(0, 1, KEY_X), | 250 | KEY(0, 1, KEY_X), |
@@ -290,27 +328,103 @@ static struct platform_device palmtc_keyboard = { | |||
290 | .platform_data = &palmtc_keypad_platform_data, | 328 | .platform_data = &palmtc_keypad_platform_data, |
291 | }, | 329 | }, |
292 | }; | 330 | }; |
331 | static void __init palmtc_mkp_init(void) | ||
332 | { | ||
333 | platform_device_register(&palmtc_keyboard); | ||
334 | } | ||
335 | #else | ||
336 | static inline void palmtc_mkp_init(void) {} | ||
337 | #endif | ||
293 | 338 | ||
294 | /****************************************************************************** | 339 | /****************************************************************************** |
295 | * UDC | 340 | * UDC |
296 | ******************************************************************************/ | 341 | ******************************************************************************/ |
297 | static struct pxa2xx_udc_mach_info palmtc_udc_info __initdata = { | 342 | #if defined(CONFIG_USB_GADGET_PXA25X)||defined(CONFIG_USB_GADGET_PXA25X_MODULE) |
343 | static struct gpio_vbus_mach_info palmtc_udc_info = { | ||
298 | .gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N, | 344 | .gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N, |
299 | .gpio_vbus_inverted = 1, | 345 | .gpio_vbus_inverted = 1, |
300 | .gpio_pullup = GPIO_NR_PALMTC_USB_POWER, | 346 | .gpio_pullup = GPIO_NR_PALMTC_USB_POWER, |
301 | }; | 347 | }; |
302 | 348 | ||
349 | static struct platform_device palmtc_gpio_vbus = { | ||
350 | .name = "gpio-vbus", | ||
351 | .id = -1, | ||
352 | .dev = { | ||
353 | .platform_data = &palmtc_udc_info, | ||
354 | }, | ||
355 | }; | ||
356 | |||
357 | static void __init palmtc_udc_init(void) | ||
358 | { | ||
359 | platform_device_register(&palmtc_gpio_vbus); | ||
360 | }; | ||
361 | #else | ||
362 | static inline void palmtc_udc_init(void) {} | ||
363 | #endif | ||
364 | |||
303 | /****************************************************************************** | 365 | /****************************************************************************** |
304 | * Touchscreen / Battery / GPIO-extender | 366 | * Touchscreen / Battery / GPIO-extender |
305 | ******************************************************************************/ | 367 | ******************************************************************************/ |
306 | static struct platform_device palmtc_ucb1400_core = { | 368 | #if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ |
369 | defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) | ||
370 | static struct platform_device palmtc_ucb1400_device = { | ||
307 | .name = "ucb1400_core", | 371 | .name = "ucb1400_core", |
308 | .id = -1, | 372 | .id = -1, |
309 | }; | 373 | }; |
310 | 374 | ||
375 | static void __init palmtc_ts_init(void) | ||
376 | { | ||
377 | pxa_set_ac97_info(NULL); | ||
378 | platform_device_register(&palmtc_ucb1400_device); | ||
379 | } | ||
380 | #else | ||
381 | static inline void palmtc_ts_init(void) {} | ||
382 | #endif | ||
383 | |||
384 | /****************************************************************************** | ||
385 | * LEDs | ||
386 | ******************************************************************************/ | ||
387 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | ||
388 | struct gpio_led palmtc_gpio_leds[] = { | ||
389 | { | ||
390 | .name = "palmtc:green:user", | ||
391 | .default_trigger = "none", | ||
392 | .gpio = GPIO_NR_PALMTC_LED_POWER, | ||
393 | .active_low = 1, | ||
394 | }, { | ||
395 | .name = "palmtc:vibra:vibra", | ||
396 | .default_trigger = "none", | ||
397 | .gpio = GPIO_NR_PALMTC_VIBRA_POWER, | ||
398 | .active_low = 1, | ||
399 | } | ||
400 | |||
401 | }; | ||
402 | |||
403 | static struct gpio_led_platform_data palmtc_gpio_led_info = { | ||
404 | .leds = palmtc_gpio_leds, | ||
405 | .num_leds = ARRAY_SIZE(palmtc_gpio_leds), | ||
406 | }; | ||
407 | |||
408 | static struct platform_device palmtc_leds = { | ||
409 | .name = "leds-gpio", | ||
410 | .id = -1, | ||
411 | .dev = { | ||
412 | .platform_data = &palmtc_gpio_led_info, | ||
413 | } | ||
414 | }; | ||
415 | |||
416 | static void __init palmtc_leds_init(void) | ||
417 | { | ||
418 | platform_device_register(&palmtc_leds); | ||
419 | } | ||
420 | #else | ||
421 | static inline void palmtc_leds_init(void) {} | ||
422 | #endif | ||
423 | |||
311 | /****************************************************************************** | 424 | /****************************************************************************** |
312 | * NOR Flash | 425 | * NOR Flash |
313 | ******************************************************************************/ | 426 | ******************************************************************************/ |
427 | #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) | ||
314 | static struct resource palmtc_flash_resource = { | 428 | static struct resource palmtc_flash_resource = { |
315 | .start = PXA_CS0_PHYS, | 429 | .start = PXA_CS0_PHYS, |
316 | .end = PXA_CS0_PHYS + SZ_16M - 1, | 430 | .end = PXA_CS0_PHYS + SZ_16M - 1, |
@@ -356,24 +470,33 @@ static struct platform_device palmtc_flash = { | |||
356 | }, | 470 | }, |
357 | }; | 471 | }; |
358 | 472 | ||
473 | static void __init palmtc_nor_init(void) | ||
474 | { | ||
475 | platform_device_register(&palmtc_flash); | ||
476 | } | ||
477 | #else | ||
478 | static inline void palmtc_nor_init(void) {} | ||
479 | #endif | ||
480 | |||
359 | /****************************************************************************** | 481 | /****************************************************************************** |
360 | * Framebuffer | 482 | * Framebuffer |
361 | ******************************************************************************/ | 483 | ******************************************************************************/ |
484 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | ||
362 | static struct pxafb_mode_info palmtc_lcd_modes[] = { | 485 | static struct pxafb_mode_info palmtc_lcd_modes[] = { |
363 | { | 486 | { |
364 | .pixclock = 115384, | 487 | .pixclock = 115384, |
365 | .xres = 320, | 488 | .xres = 320, |
366 | .yres = 320, | 489 | .yres = 320, |
367 | .bpp = 16, | 490 | .bpp = 16, |
368 | 491 | ||
369 | .left_margin = 27, | 492 | .left_margin = 27, |
370 | .right_margin = 7, | 493 | .right_margin = 7, |
371 | .upper_margin = 7, | 494 | .upper_margin = 7, |
372 | .lower_margin = 8, | 495 | .lower_margin = 8, |
373 | 496 | ||
374 | .hsync_len = 6, | 497 | .hsync_len = 6, |
375 | .vsync_len = 1, | 498 | .vsync_len = 1, |
376 | }, | 499 | }, |
377 | }; | 500 | }; |
378 | 501 | ||
379 | static struct pxafb_mach_info palmtc_lcd_screen = { | 502 | static struct pxafb_mach_info palmtc_lcd_screen = { |
@@ -382,17 +505,17 @@ static struct pxafb_mach_info palmtc_lcd_screen = { | |||
382 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, | 505 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, |
383 | }; | 506 | }; |
384 | 507 | ||
508 | static void __init palmtc_lcd_init(void) | ||
509 | { | ||
510 | set_pxa_fb_info(&palmtc_lcd_screen); | ||
511 | } | ||
512 | #else | ||
513 | static inline void palmtc_lcd_init(void) {} | ||
514 | #endif | ||
515 | |||
385 | /****************************************************************************** | 516 | /****************************************************************************** |
386 | * Machine init | 517 | * Machine init |
387 | ******************************************************************************/ | 518 | ******************************************************************************/ |
388 | static struct platform_device *devices[] __initdata = { | ||
389 | &palmtc_backlight, | ||
390 | &palmtc_ucb1400_core, | ||
391 | &palmtc_keyboard, | ||
392 | &palmtc_pxa_keys, | ||
393 | &palmtc_flash, | ||
394 | }; | ||
395 | |||
396 | static void __init palmtc_init(void) | 519 | static void __init palmtc_init(void) |
397 | { | 520 | { |
398 | pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config)); | 521 | pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config)); |
@@ -402,18 +525,21 @@ static void __init palmtc_init(void) | |||
402 | pxa_set_stuart_info(NULL); | 525 | pxa_set_stuart_info(NULL); |
403 | pxa_set_hwuart_info(NULL); | 526 | pxa_set_hwuart_info(NULL); |
404 | 527 | ||
405 | set_pxa_fb_info(&palmtc_lcd_screen); | 528 | palmtc_mmc_init(); |
406 | pxa_set_mci_info(&palmtc_mci_platform_data); | 529 | palmtc_keys_init(); |
407 | pxa_set_udc_info(&palmtc_udc_info); | 530 | palmtc_pwm_init(); |
408 | pxa_set_ac97_info(NULL); | 531 | palmtc_irda_init(); |
409 | pxa_set_ficp_info(&palmtc_ficp_platform_data); | 532 | palmtc_mkp_init(); |
410 | 533 | palmtc_udc_init(); | |
411 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 534 | palmtc_ts_init(); |
535 | palmtc_nor_init(); | ||
536 | palmtc_lcd_init(); | ||
537 | palmtc_leds_init(); | ||
412 | }; | 538 | }; |
413 | 539 | ||
414 | MACHINE_START(PALMTC, "Palm Tungsten|C") | 540 | MACHINE_START(PALMTC, "Palm Tungsten|C") |
415 | .boot_params = 0xa0000100, | 541 | .boot_params = 0xa0000100, |
416 | .map_io = pxa_map_io, | 542 | .map_io = pxa25x_map_io, |
417 | .init_irq = pxa25x_init_irq, | 543 | .init_irq = pxa25x_init_irq, |
418 | .timer = &pxa_timer, | 544 | .timer = &pxa_timer, |
419 | .init_machine = palmtc_init | 545 | .init_machine = palmtc_init |
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index a9dae7bc35d9..3f25014a136c 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c | |||
@@ -374,7 +374,7 @@ static void __init palmte2_init(void) | |||
374 | 374 | ||
375 | MACHINE_START(PALMTE2, "Palm Tungsten|E2") | 375 | MACHINE_START(PALMTE2, "Palm Tungsten|E2") |
376 | .boot_params = 0xa0000100, | 376 | .boot_params = 0xa0000100, |
377 | .map_io = pxa_map_io, | 377 | .map_io = pxa25x_map_io, |
378 | .init_irq = pxa25x_init_irq, | 378 | .init_irq = pxa25x_init_irq, |
379 | .timer = &pxa_timer, | 379 | .timer = &pxa_timer, |
380 | .init_machine = palmte2_init | 380 | .init_machine = palmte2_init |
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index 00e2d7ba84ed..8aadad55fbe4 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c | |||
@@ -442,7 +442,7 @@ static void __init centro_init(void) | |||
442 | 442 | ||
443 | MACHINE_START(TREO680, "Palm Treo 680") | 443 | MACHINE_START(TREO680, "Palm Treo 680") |
444 | .boot_params = 0xa0000100, | 444 | .boot_params = 0xa0000100, |
445 | .map_io = pxa_map_io, | 445 | .map_io = pxa27x_map_io, |
446 | .reserve = treo_reserve, | 446 | .reserve = treo_reserve, |
447 | .init_irq = pxa27x_init_irq, | 447 | .init_irq = pxa27x_init_irq, |
448 | .timer = &pxa_timer, | 448 | .timer = &pxa_timer, |
@@ -451,7 +451,7 @@ MACHINE_END | |||
451 | 451 | ||
452 | MACHINE_START(CENTRO, "Palm Centro 685") | 452 | MACHINE_START(CENTRO, "Palm Centro 685") |
453 | .boot_params = 0xa0000100, | 453 | .boot_params = 0xa0000100, |
454 | .map_io = pxa_map_io, | 454 | .map_io = pxa27x_map_io, |
455 | .reserve = treo_reserve, | 455 | .reserve = treo_reserve, |
456 | .init_irq = pxa27x_init_irq, | 456 | .init_irq = pxa27x_init_irq, |
457 | .timer = &pxa_timer, | 457 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index d2060a1d1d68..595f002066cc 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c | |||
@@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {} | |||
241 | /****************************************************************************** | 241 | /****************************************************************************** |
242 | * NAND Flash | 242 | * NAND Flash |
243 | ******************************************************************************/ | 243 | ******************************************************************************/ |
244 | #if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE) | 244 | #if defined(CONFIG_MTD_NAND_PLATFORM) || \ |
245 | defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | ||
245 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, | 246 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, |
246 | unsigned int ctrl) | 247 | unsigned int ctrl) |
247 | { | 248 | { |
@@ -333,7 +334,7 @@ static struct map_desc palmtx_io_desc[] __initdata = { | |||
333 | 334 | ||
334 | static void __init palmtx_map_io(void) | 335 | static void __init palmtx_map_io(void) |
335 | { | 336 | { |
336 | pxa_map_io(); | 337 | pxa27x_map_io(); |
337 | iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc)); | 338 | iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc)); |
338 | } | 339 | } |
339 | 340 | ||
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index af6203fbca9c..7bf4017326e3 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c | |||
@@ -280,7 +280,7 @@ static void __init palmz72_init(void) | |||
280 | 280 | ||
281 | MACHINE_START(PALMZ72, "Palm Zire72") | 281 | MACHINE_START(PALMZ72, "Palm Zire72") |
282 | .boot_params = 0xa0000100, | 282 | .boot_params = 0xa0000100, |
283 | .map_io = pxa_map_io, | 283 | .map_io = pxa27x_map_io, |
284 | .init_irq = pxa27x_init_irq, | 284 | .init_irq = pxa27x_init_irq, |
285 | .timer = &pxa_timer, | 285 | .timer = &pxa_timer, |
286 | .init_machine = palmz72_init | 286 | .init_machine = palmz72_init |
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index c77e8f30a439..8547c9abc40a 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c | |||
@@ -244,7 +244,7 @@ static void __init pcm027_init(void) | |||
244 | 244 | ||
245 | static void __init pcm027_map_io(void) | 245 | static void __init pcm027_map_io(void) |
246 | { | 246 | { |
247 | pxa_map_io(); | 247 | pxa27x_map_io(); |
248 | 248 | ||
249 | /* initialize sleep mode regs (wake-up sources, etc) */ | 249 | /* initialize sleep mode regs (wake-up sources, etc) */ |
250 | PGSR0 = 0x01308000; | 250 | PGSR0 = 0x01308000; |
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 93a191c889df..8451790cb48d 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c | |||
@@ -466,7 +466,7 @@ static void __init fixup_poodle(struct machine_desc *desc, | |||
466 | 466 | ||
467 | MACHINE_START(POODLE, "SHARP Poodle") | 467 | MACHINE_START(POODLE, "SHARP Poodle") |
468 | .fixup = fixup_poodle, | 468 | .fixup = fixup_poodle, |
469 | .map_io = pxa_map_io, | 469 | .map_io = pxa25x_map_io, |
470 | .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */ | 470 | .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */ |
471 | .init_irq = pxa25x_init_irq, | 471 | .init_irq = pxa25x_init_irq, |
472 | .timer = &pxa_timer, | 472 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index de53f2e4aa39..3f5241c84894 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
25 | 25 | ||
26 | #include <asm/mach/map.h> | ||
26 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
27 | #include <mach/irqs.h> | 28 | #include <mach/irqs.h> |
28 | #include <mach/gpio.h> | 29 | #include <mach/gpio.h> |
@@ -30,6 +31,7 @@ | |||
30 | #include <mach/reset.h> | 31 | #include <mach/reset.h> |
31 | #include <mach/pm.h> | 32 | #include <mach/pm.h> |
32 | #include <mach/dma.h> | 33 | #include <mach/dma.h> |
34 | #include <mach/smemc.h> | ||
33 | 35 | ||
34 | #include "generic.h" | 36 | #include "generic.h" |
35 | #include "devices.h" | 37 | #include "devices.h" |
@@ -90,23 +92,21 @@ unsigned int pxa25x_get_clk_frequency_khz(int info) | |||
90 | return (turbo & 1) ? (N/1000) : (M/1000); | 92 | return (turbo & 1) ? (N/1000) : (M/1000); |
91 | } | 93 | } |
92 | 94 | ||
93 | /* | 95 | static unsigned long clk_pxa25x_mem_getrate(struct clk *clk) |
94 | * Return the current memory clock frequency in units of 10kHz | ||
95 | */ | ||
96 | unsigned int pxa25x_get_memclk_frequency_10khz(void) | ||
97 | { | 96 | { |
98 | return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000; | 97 | return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK; |
99 | } | 98 | } |
100 | 99 | ||
101 | static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk) | 100 | static const struct clkops clk_pxa25x_mem_ops = { |
102 | { | 101 | .enable = clk_dummy_enable, |
103 | return pxa25x_get_memclk_frequency_10khz() * 10000; | 102 | .disable = clk_dummy_disable, |
104 | } | 103 | .getrate = clk_pxa25x_mem_getrate, |
104 | }; | ||
105 | 105 | ||
106 | static const struct clkops clk_pxa25x_lcd_ops = { | 106 | static const struct clkops clk_pxa25x_lcd_ops = { |
107 | .enable = clk_cken_enable, | 107 | .enable = clk_pxa2xx_cken_enable, |
108 | .disable = clk_cken_disable, | 108 | .disable = clk_pxa2xx_cken_disable, |
109 | .getrate = clk_pxa25x_lcd_getrate, | 109 | .getrate = clk_pxa25x_mem_getrate, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static unsigned long gpio12_config_32k[] = { | 112 | static unsigned long gpio12_config_32k[] = { |
@@ -160,31 +160,30 @@ static const struct clkops clk_pxa25x_gpio11_ops = { | |||
160 | * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz | 160 | * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz |
161 | * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) | 161 | * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) |
162 | */ | 162 | */ |
163 | static DEFINE_CKEN(pxa25x_hwuart, HWUART, 14745600, 1); | ||
164 | |||
165 | static struct clk_lookup pxa25x_hwuart_clkreg = | ||
166 | INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL); | ||
167 | 163 | ||
168 | /* | 164 | /* |
169 | * PXA 2xx clock declarations. | 165 | * PXA 2xx clock declarations. |
170 | */ | 166 | */ |
167 | static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1); | ||
168 | static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1); | ||
169 | static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1); | ||
170 | static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1); | ||
171 | static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5); | ||
172 | static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0); | ||
173 | static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0); | ||
174 | static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0); | ||
175 | static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0); | ||
176 | static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0); | ||
177 | static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0); | ||
178 | static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0); | ||
179 | static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0); | ||
180 | static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0); | ||
181 | static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0); | ||
182 | |||
171 | static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops); | 183 | static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops); |
172 | static DEFINE_CKEN(pxa25x_ffuart, FFUART, 14745600, 1); | ||
173 | static DEFINE_CKEN(pxa25x_btuart, BTUART, 14745600, 1); | ||
174 | static DEFINE_CKEN(pxa25x_stuart, STUART, 14745600, 1); | ||
175 | static DEFINE_CKEN(pxa25x_usb, USB, 47923000, 5); | ||
176 | static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0); | 184 | static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0); |
177 | static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0); | 185 | static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0); |
178 | static DEFINE_CKEN(pxa25x_mmc, MMC, 19169000, 0); | 186 | static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0); |
179 | static DEFINE_CKEN(pxa25x_i2c, I2C, 31949000, 0); | ||
180 | static DEFINE_CKEN(pxa25x_ssp, SSP, 3686400, 0); | ||
181 | static DEFINE_CKEN(pxa25x_nssp, NSSP, 3686400, 0); | ||
182 | static DEFINE_CKEN(pxa25x_assp, ASSP, 3686400, 0); | ||
183 | static DEFINE_CKEN(pxa25x_pwm0, PWM0, 3686400, 0); | ||
184 | static DEFINE_CKEN(pxa25x_pwm1, PWM1, 3686400, 0); | ||
185 | static DEFINE_CKEN(pxa25x_ac97, AC97, 24576000, 0); | ||
186 | static DEFINE_CKEN(pxa25x_i2s, I2S, 14745600, 0); | ||
187 | static DEFINE_CKEN(pxa25x_ficp, FICP, 47923000, 0); | ||
188 | 187 | ||
189 | static struct clk_lookup pxa25x_clkregs[] = { | 188 | static struct clk_lookup pxa25x_clkregs[] = { |
190 | INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL), | 189 | INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL), |
@@ -205,8 +204,12 @@ static struct clk_lookup pxa25x_clkregs[] = { | |||
205 | INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"), | 204 | INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"), |
206 | INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), | 205 | INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), |
207 | INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), | 206 | INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), |
207 | INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), | ||
208 | }; | 208 | }; |
209 | 209 | ||
210 | static struct clk_lookup pxa25x_hwuart_clkreg = | ||
211 | INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL); | ||
212 | |||
210 | #ifdef CONFIG_PM | 213 | #ifdef CONFIG_PM |
211 | 214 | ||
212 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 215 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
@@ -219,20 +222,17 @@ static struct clk_lookup pxa25x_clkregs[] = { | |||
219 | */ | 222 | */ |
220 | enum { | 223 | enum { |
221 | SLEEP_SAVE_PSTR, | 224 | SLEEP_SAVE_PSTR, |
222 | SLEEP_SAVE_CKEN, | ||
223 | SLEEP_SAVE_COUNT | 225 | SLEEP_SAVE_COUNT |
224 | }; | 226 | }; |
225 | 227 | ||
226 | 228 | ||
227 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | 229 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) |
228 | { | 230 | { |
229 | SAVE(CKEN); | ||
230 | SAVE(PSTR); | 231 | SAVE(PSTR); |
231 | } | 232 | } |
232 | 233 | ||
233 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | 234 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) |
234 | { | 235 | { |
235 | RESTORE(CKEN); | ||
236 | RESTORE(PSTR); | 236 | RESTORE(PSTR); |
237 | } | 237 | } |
238 | 238 | ||
@@ -320,6 +320,22 @@ void __init pxa26x_init_irq(void) | |||
320 | } | 320 | } |
321 | #endif | 321 | #endif |
322 | 322 | ||
323 | static struct map_desc pxa25x_io_desc[] __initdata = { | ||
324 | { /* Mem Ctl */ | ||
325 | .virtual = SMEMC_VIRT, | ||
326 | .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE), | ||
327 | .length = 0x00200000, | ||
328 | .type = MT_DEVICE | ||
329 | }, | ||
330 | }; | ||
331 | |||
332 | void __init pxa25x_map_io(void) | ||
333 | { | ||
334 | pxa_map_io(); | ||
335 | iotable_init(ARRAY_AND_SIZE(pxa25x_io_desc)); | ||
336 | pxa25x_get_clk_frequency_khz(1); | ||
337 | } | ||
338 | |||
323 | static struct platform_device *pxa25x_devices[] __initdata = { | 339 | static struct platform_device *pxa25x_devices[] __initdata = { |
324 | &pxa25x_device_udc, | 340 | &pxa25x_device_udc, |
325 | &pxa_device_pmu, | 341 | &pxa_device_pmu, |
@@ -339,7 +355,9 @@ static struct sys_device pxa25x_sysdev[] = { | |||
339 | .cls = &pxa2xx_mfp_sysclass, | 355 | .cls = &pxa2xx_mfp_sysclass, |
340 | }, { | 356 | }, { |
341 | .cls = &pxa_gpio_sysclass, | 357 | .cls = &pxa_gpio_sysclass, |
342 | }, | 358 | }, { |
359 | .cls = &pxa2xx_clock_sysclass, | ||
360 | } | ||
343 | }; | 361 | }; |
344 | 362 | ||
345 | static int __init pxa25x_init(void) | 363 | static int __init pxa25x_init(void) |
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index d1fbf29d561c..b2130b7a7b52 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -17,7 +17,9 @@ | |||
17 | #include <linux/suspend.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/sysdev.h> | 19 | #include <linux/sysdev.h> |
20 | #include <linux/io.h> | ||
20 | 21 | ||
22 | #include <asm/mach/map.h> | ||
21 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
22 | #include <asm/irq.h> | 24 | #include <asm/irq.h> |
23 | #include <mach/irqs.h> | 25 | #include <mach/irqs.h> |
@@ -27,6 +29,8 @@ | |||
27 | #include <mach/ohci.h> | 29 | #include <mach/ohci.h> |
28 | #include <mach/pm.h> | 30 | #include <mach/pm.h> |
29 | #include <mach/dma.h> | 31 | #include <mach/dma.h> |
32 | #include <mach/smemc.h> | ||
33 | |||
30 | #include <plat/i2c.h> | 34 | #include <plat/i2c.h> |
31 | 35 | ||
32 | #include "generic.h" | 36 | #include "generic.h" |
@@ -107,10 +111,9 @@ unsigned int pxa27x_get_clk_frequency_khz(int info) | |||
107 | } | 111 | } |
108 | 112 | ||
109 | /* | 113 | /* |
110 | * Return the current mem clock frequency in units of 10kHz as | 114 | * Return the current mem clock frequency as reflected by CCCR[A], B, and L |
111 | * reflected by CCCR[A], B, and L | ||
112 | */ | 115 | */ |
113 | unsigned int pxa27x_get_memclk_frequency_10khz(void) | 116 | static unsigned long clk_pxa27x_mem_getrate(struct clk *clk) |
114 | { | 117 | { |
115 | unsigned long ccsr, clkcfg; | 118 | unsigned long ccsr, clkcfg; |
116 | unsigned int l, L, m, M; | 119 | unsigned int l, L, m, M; |
@@ -129,9 +132,15 @@ unsigned int pxa27x_get_memclk_frequency_10khz(void) | |||
129 | L = l * BASE_CLK; | 132 | L = l * BASE_CLK; |
130 | M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); | 133 | M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); |
131 | 134 | ||
132 | return (M / 10000); | 135 | return M; |
133 | } | 136 | } |
134 | 137 | ||
138 | static const struct clkops clk_pxa27x_mem_ops = { | ||
139 | .enable = clk_dummy_enable, | ||
140 | .disable = clk_dummy_disable, | ||
141 | .getrate = clk_pxa27x_mem_getrate, | ||
142 | }; | ||
143 | |||
135 | /* | 144 | /* |
136 | * Return the current LCD clock frequency in units of 10kHz as | 145 | * Return the current LCD clock frequency in units of 10kHz as |
137 | */ | 146 | */ |
@@ -157,36 +166,38 @@ static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk) | |||
157 | } | 166 | } |
158 | 167 | ||
159 | static const struct clkops clk_pxa27x_lcd_ops = { | 168 | static const struct clkops clk_pxa27x_lcd_ops = { |
160 | .enable = clk_cken_enable, | 169 | .enable = clk_pxa2xx_cken_enable, |
161 | .disable = clk_cken_disable, | 170 | .disable = clk_pxa2xx_cken_disable, |
162 | .getrate = clk_pxa27x_lcd_getrate, | 171 | .getrate = clk_pxa27x_lcd_getrate, |
163 | }; | 172 | }; |
164 | 173 | ||
174 | static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); | ||
175 | static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1); | ||
176 | static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1); | ||
177 | static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0); | ||
178 | static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0); | ||
179 | static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5); | ||
180 | static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0); | ||
181 | static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0); | ||
182 | static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); | ||
183 | static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); | ||
184 | static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); | ||
185 | static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); | ||
186 | static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); | ||
187 | static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); | ||
188 | static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); | ||
189 | static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); | ||
190 | static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0); | ||
191 | static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); | ||
192 | static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0); | ||
193 | static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0); | ||
194 | static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); | ||
195 | static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0); | ||
196 | static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0); | ||
197 | |||
165 | static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops); | 198 | static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops); |
166 | static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops); | 199 | static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops); |
167 | static DEFINE_CKEN(pxa27x_ffuart, FFUART, 14857000, 1); | 200 | static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0); |
168 | static DEFINE_CKEN(pxa27x_btuart, BTUART, 14857000, 1); | ||
169 | static DEFINE_CKEN(pxa27x_stuart, STUART, 14857000, 1); | ||
170 | static DEFINE_CKEN(pxa27x_i2s, I2S, 14682000, 0); | ||
171 | static DEFINE_CKEN(pxa27x_i2c, I2C, 32842000, 0); | ||
172 | static DEFINE_CKEN(pxa27x_usb, USB, 48000000, 5); | ||
173 | static DEFINE_CKEN(pxa27x_mmc, MMC, 19500000, 0); | ||
174 | static DEFINE_CKEN(pxa27x_ficp, FICP, 48000000, 0); | ||
175 | static DEFINE_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0); | ||
176 | static DEFINE_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0); | ||
177 | static DEFINE_CKEN(pxa27x_keypad, KEYPAD, 32768, 0); | ||
178 | static DEFINE_CKEN(pxa27x_ssp1, SSP1, 13000000, 0); | ||
179 | static DEFINE_CKEN(pxa27x_ssp2, SSP2, 13000000, 0); | ||
180 | static DEFINE_CKEN(pxa27x_ssp3, SSP3, 13000000, 0); | ||
181 | static DEFINE_CKEN(pxa27x_pwm0, PWM0, 13000000, 0); | ||
182 | static DEFINE_CKEN(pxa27x_pwm1, PWM1, 13000000, 0); | ||
183 | static DEFINE_CKEN(pxa27x_ac97, AC97, 24576000, 0); | ||
184 | static DEFINE_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0); | ||
185 | static DEFINE_CKEN(pxa27x_msl, MSL, 48000000, 0); | ||
186 | static DEFINE_CKEN(pxa27x_usim, USIM, 48000000, 0); | ||
187 | static DEFINE_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0); | ||
188 | static DEFINE_CKEN(pxa27x_im, IM, 0, 0); | ||
189 | static DEFINE_CKEN(pxa27x_memc, MEMC, 0, 0); | ||
190 | 201 | ||
191 | static struct clk_lookup pxa27x_clkregs[] = { | 202 | static struct clk_lookup pxa27x_clkregs[] = { |
192 | INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL), | 203 | INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL), |
@@ -215,6 +226,7 @@ static struct clk_lookup pxa27x_clkregs[] = { | |||
215 | INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"), | 226 | INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"), |
216 | INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), | 227 | INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), |
217 | INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), | 228 | INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), |
229 | INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), | ||
218 | }; | 230 | }; |
219 | 231 | ||
220 | #ifdef CONFIG_PM | 232 | #ifdef CONFIG_PM |
@@ -246,7 +258,6 @@ int __init pxa27x_set_pwrmode(unsigned int mode) | |||
246 | */ | 258 | */ |
247 | enum { | 259 | enum { |
248 | SLEEP_SAVE_PSTR, | 260 | SLEEP_SAVE_PSTR, |
249 | SLEEP_SAVE_CKEN, | ||
250 | SLEEP_SAVE_MDREFR, | 261 | SLEEP_SAVE_MDREFR, |
251 | SLEEP_SAVE_PCFR, | 262 | SLEEP_SAVE_PCFR, |
252 | SLEEP_SAVE_COUNT | 263 | SLEEP_SAVE_COUNT |
@@ -254,21 +265,19 @@ enum { | |||
254 | 265 | ||
255 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) | 266 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) |
256 | { | 267 | { |
257 | SAVE(MDREFR); | 268 | sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR); |
258 | SAVE(PCFR); | 269 | SAVE(PCFR); |
259 | 270 | ||
260 | SAVE(CKEN); | ||
261 | SAVE(PSTR); | 271 | SAVE(PSTR); |
262 | } | 272 | } |
263 | 273 | ||
264 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | 274 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) |
265 | { | 275 | { |
266 | RESTORE(MDREFR); | 276 | __raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR); |
267 | RESTORE(PCFR); | 277 | RESTORE(PCFR); |
268 | 278 | ||
269 | PSSR = PSSR_RDH | PSSR_PH; | 279 | PSSR = PSSR_RDH | PSSR_PH; |
270 | 280 | ||
271 | RESTORE(CKEN); | ||
272 | RESTORE(PSTR); | 281 | RESTORE(PSTR); |
273 | } | 282 | } |
274 | 283 | ||
@@ -370,6 +379,27 @@ void __init pxa27x_init_irq(void) | |||
370 | pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake); | 379 | pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake); |
371 | } | 380 | } |
372 | 381 | ||
382 | static struct map_desc pxa27x_io_desc[] __initdata = { | ||
383 | { /* Mem Ctl */ | ||
384 | .virtual = SMEMC_VIRT, | ||
385 | .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE), | ||
386 | .length = 0x00200000, | ||
387 | .type = MT_DEVICE | ||
388 | }, { /* IMem ctl */ | ||
389 | .virtual = 0xfe000000, | ||
390 | .pfn = __phys_to_pfn(0x58000000), | ||
391 | .length = 0x00100000, | ||
392 | .type = MT_DEVICE | ||
393 | }, | ||
394 | }; | ||
395 | |||
396 | void __init pxa27x_map_io(void) | ||
397 | { | ||
398 | pxa_map_io(); | ||
399 | iotable_init(ARRAY_AND_SIZE(pxa27x_io_desc)); | ||
400 | pxa27x_get_clk_frequency_khz(1); | ||
401 | } | ||
402 | |||
373 | /* | 403 | /* |
374 | * device registration specific to PXA27x. | 404 | * device registration specific to PXA27x. |
375 | */ | 405 | */ |
@@ -405,7 +435,9 @@ static struct sys_device pxa27x_sysdev[] = { | |||
405 | .cls = &pxa2xx_mfp_sysclass, | 435 | .cls = &pxa2xx_mfp_sysclass, |
406 | }, { | 436 | }, { |
407 | .cls = &pxa_gpio_sysclass, | 437 | .cls = &pxa_gpio_sysclass, |
408 | }, | 438 | }, { |
439 | .cls = &pxa2xx_clock_sysclass, | ||
440 | } | ||
409 | }; | 441 | }; |
410 | 442 | ||
411 | static int __init pxa27x_init(void) | 443 | static int __init pxa27x_init(void) |
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index d1c747cdacf8..e14818f5d950 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/sysdev.h> | 23 | #include <linux/sysdev.h> |
24 | 24 | ||
25 | #include <asm/mach/map.h> | ||
25 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
26 | #include <mach/gpio.h> | 27 | #include <mach/gpio.h> |
27 | #include <mach/pxa3xx-regs.h> | 28 | #include <mach/pxa3xx-regs.h> |
@@ -30,193 +31,16 @@ | |||
30 | #include <mach/pm.h> | 31 | #include <mach/pm.h> |
31 | #include <mach/dma.h> | 32 | #include <mach/dma.h> |
32 | #include <mach/regs-intc.h> | 33 | #include <mach/regs-intc.h> |
34 | #include <mach/smemc.h> | ||
33 | #include <plat/i2c.h> | 35 | #include <plat/i2c.h> |
34 | 36 | ||
35 | #include "generic.h" | 37 | #include "generic.h" |
36 | #include "devices.h" | 38 | #include "devices.h" |
37 | #include "clock.h" | 39 | #include "clock.h" |
38 | 40 | ||
39 | /* Crystal clock: 13MHz */ | ||
40 | #define BASE_CLK 13000000 | ||
41 | |||
42 | /* Ring Oscillator Clock: 60MHz */ | ||
43 | #define RO_CLK 60000000 | ||
44 | |||
45 | #define ACCR_D0CS (1 << 26) | ||
46 | #define ACCR_PCCE (1 << 11) | ||
47 | |||
48 | #define PECR_IE(n) ((1 << ((n) * 2)) << 28) | 41 | #define PECR_IE(n) ((1 << ((n) * 2)) << 28) |
49 | #define PECR_IS(n) ((1 << ((n) * 2)) << 29) | 42 | #define PECR_IS(n) ((1 << ((n) * 2)) << 29) |
50 | 43 | ||
51 | /* crystal frequency to static memory controller multiplier (SMCFS) */ | ||
52 | static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; | ||
53 | |||
54 | /* crystal frequency to HSIO bus frequency multiplier (HSS) */ | ||
55 | static unsigned char hss_mult[4] = { 8, 12, 16, 24 }; | ||
56 | |||
57 | /* | ||
58 | * Get the clock frequency as reflected by CCSR and the turbo flag. | ||
59 | * We assume these values have been applied via a fcs. | ||
60 | * If info is not 0 we also display the current settings. | ||
61 | */ | ||
62 | unsigned int pxa3xx_get_clk_frequency_khz(int info) | ||
63 | { | ||
64 | unsigned long acsr, xclkcfg; | ||
65 | unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS; | ||
66 | |||
67 | /* Read XCLKCFG register turbo bit */ | ||
68 | __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg)); | ||
69 | t = xclkcfg & 0x1; | ||
70 | |||
71 | acsr = ACSR; | ||
72 | |||
73 | xl = acsr & 0x1f; | ||
74 | xn = (acsr >> 8) & 0x7; | ||
75 | hss = (acsr >> 14) & 0x3; | ||
76 | |||
77 | XL = xl * BASE_CLK; | ||
78 | XN = xn * XL; | ||
79 | |||
80 | ro = acsr & ACCR_D0CS; | ||
81 | |||
82 | CLK = (ro) ? RO_CLK : ((t) ? XN : XL); | ||
83 | HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK; | ||
84 | |||
85 | if (info) { | ||
86 | pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n", | ||
87 | RO_CLK / 1000000, (RO_CLK % 1000000) / 10000, | ||
88 | (ro) ? "" : "in"); | ||
89 | pr_info("Run Mode clock: %d.%02dMHz (*%d)\n", | ||
90 | XL / 1000000, (XL % 1000000) / 10000, xl); | ||
91 | pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n", | ||
92 | XN / 1000000, (XN % 1000000) / 10000, xn, | ||
93 | (t) ? "" : "in"); | ||
94 | pr_info("HSIO bus clock: %d.%02dMHz\n", | ||
95 | HSS / 1000000, (HSS % 1000000) / 10000); | ||
96 | } | ||
97 | |||
98 | return CLK / 1000; | ||
99 | } | ||
100 | |||
101 | void pxa3xx_clear_reset_status(unsigned int mask) | ||
102 | { | ||
103 | /* RESET_STATUS_* has a 1:1 mapping with ARSR */ | ||
104 | ARSR = mask; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Return the current AC97 clock frequency. | ||
109 | */ | ||
110 | static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk) | ||
111 | { | ||
112 | unsigned long rate = 312000000; | ||
113 | unsigned long ac97_div; | ||
114 | |||
115 | ac97_div = AC97_DIV; | ||
116 | |||
117 | /* This may loose precision for some rates but won't for the | ||
118 | * standard 24.576MHz. | ||
119 | */ | ||
120 | rate /= (ac97_div >> 12) & 0x7fff; | ||
121 | rate *= (ac97_div & 0xfff); | ||
122 | |||
123 | return rate; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Return the current HSIO bus clock frequency | ||
128 | */ | ||
129 | static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk) | ||
130 | { | ||
131 | unsigned long acsr; | ||
132 | unsigned int hss, hsio_clk; | ||
133 | |||
134 | acsr = ACSR; | ||
135 | |||
136 | hss = (acsr >> 14) & 0x3; | ||
137 | hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK; | ||
138 | |||
139 | return hsio_clk; | ||
140 | } | ||
141 | |||
142 | void clk_pxa3xx_cken_enable(struct clk *clk) | ||
143 | { | ||
144 | unsigned long mask = 1ul << (clk->cken & 0x1f); | ||
145 | |||
146 | if (clk->cken < 32) | ||
147 | CKENA |= mask; | ||
148 | else | ||
149 | CKENB |= mask; | ||
150 | } | ||
151 | |||
152 | void clk_pxa3xx_cken_disable(struct clk *clk) | ||
153 | { | ||
154 | unsigned long mask = 1ul << (clk->cken & 0x1f); | ||
155 | |||
156 | if (clk->cken < 32) | ||
157 | CKENA &= ~mask; | ||
158 | else | ||
159 | CKENB &= ~mask; | ||
160 | } | ||
161 | |||
162 | const struct clkops clk_pxa3xx_cken_ops = { | ||
163 | .enable = clk_pxa3xx_cken_enable, | ||
164 | .disable = clk_pxa3xx_cken_disable, | ||
165 | }; | ||
166 | |||
167 | static const struct clkops clk_pxa3xx_hsio_ops = { | ||
168 | .enable = clk_pxa3xx_cken_enable, | ||
169 | .disable = clk_pxa3xx_cken_disable, | ||
170 | .getrate = clk_pxa3xx_hsio_getrate, | ||
171 | }; | ||
172 | |||
173 | static const struct clkops clk_pxa3xx_ac97_ops = { | ||
174 | .enable = clk_pxa3xx_cken_enable, | ||
175 | .disable = clk_pxa3xx_cken_disable, | ||
176 | .getrate = clk_pxa3xx_ac97_getrate, | ||
177 | }; | ||
178 | |||
179 | static void clk_pout_enable(struct clk *clk) | ||
180 | { | ||
181 | OSCC |= OSCC_PEN; | ||
182 | } | ||
183 | |||
184 | static void clk_pout_disable(struct clk *clk) | ||
185 | { | ||
186 | OSCC &= ~OSCC_PEN; | ||
187 | } | ||
188 | |||
189 | static const struct clkops clk_pout_ops = { | ||
190 | .enable = clk_pout_enable, | ||
191 | .disable = clk_pout_disable, | ||
192 | }; | ||
193 | |||
194 | static void clk_dummy_enable(struct clk *clk) | ||
195 | { | ||
196 | } | ||
197 | |||
198 | static void clk_dummy_disable(struct clk *clk) | ||
199 | { | ||
200 | } | ||
201 | |||
202 | static const struct clkops clk_dummy_ops = { | ||
203 | .enable = clk_dummy_enable, | ||
204 | .disable = clk_dummy_disable, | ||
205 | }; | ||
206 | |||
207 | static struct clk clk_pxa3xx_pout = { | ||
208 | .ops = &clk_pout_ops, | ||
209 | .rate = 13000000, | ||
210 | .delay = 70, | ||
211 | }; | ||
212 | |||
213 | static struct clk clk_dummy = { | ||
214 | .ops = &clk_dummy_ops, | ||
215 | }; | ||
216 | |||
217 | static DEFINE_PXA3_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); | ||
218 | static DEFINE_PXA3_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); | ||
219 | static DEFINE_PXA3_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); | ||
220 | static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); | 44 | static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1); |
221 | static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); | 45 | static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1); |
222 | static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); | 46 | static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1); |
@@ -234,6 +58,12 @@ static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0); | |||
234 | static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); | 58 | static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); |
235 | static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); | 59 | static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); |
236 | 60 | ||
61 | static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); | ||
62 | static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops); | ||
63 | static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops); | ||
64 | static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops); | ||
65 | static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70); | ||
66 | |||
237 | static struct clk_lookup pxa3xx_clkregs[] = { | 67 | static struct clk_lookup pxa3xx_clkregs[] = { |
238 | INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), | 68 | INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), |
239 | /* Power I2C clock is always on */ | 69 | /* Power I2C clock is always on */ |
@@ -258,6 +88,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { | |||
258 | INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL), | 88 | INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL), |
259 | INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), | 89 | INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), |
260 | INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), | 90 | INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), |
91 | INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL), | ||
261 | }; | 92 | }; |
262 | 93 | ||
263 | #ifdef CONFIG_PM | 94 | #ifdef CONFIG_PM |
@@ -268,30 +99,6 @@ static struct clk_lookup pxa3xx_clkregs[] = { | |||
268 | static void __iomem *sram; | 99 | static void __iomem *sram; |
269 | static unsigned long wakeup_src; | 100 | static unsigned long wakeup_src; |
270 | 101 | ||
271 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | ||
272 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | ||
273 | |||
274 | enum { SLEEP_SAVE_CKENA, | ||
275 | SLEEP_SAVE_CKENB, | ||
276 | SLEEP_SAVE_ACCR, | ||
277 | |||
278 | SLEEP_SAVE_COUNT, | ||
279 | }; | ||
280 | |||
281 | static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) | ||
282 | { | ||
283 | SAVE(CKENA); | ||
284 | SAVE(CKENB); | ||
285 | SAVE(ACCR); | ||
286 | } | ||
287 | |||
288 | static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save) | ||
289 | { | ||
290 | RESTORE(ACCR); | ||
291 | RESTORE(CKENA); | ||
292 | RESTORE(CKENB); | ||
293 | } | ||
294 | |||
295 | /* | 102 | /* |
296 | * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic | 103 | * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic |
297 | * memory controller has to be reinitialised, so we place some code | 104 | * memory controller has to be reinitialised, so we place some code |
@@ -390,9 +197,6 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state) | |||
390 | } | 197 | } |
391 | 198 | ||
392 | static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { | 199 | static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = { |
393 | .save_count = SLEEP_SAVE_COUNT, | ||
394 | .save = pxa3xx_cpu_pm_save, | ||
395 | .restore = pxa3xx_cpu_pm_restore, | ||
396 | .valid = pxa3xx_cpu_pm_valid, | 200 | .valid = pxa3xx_cpu_pm_valid, |
397 | .enter = pxa3xx_cpu_pm_enter, | 201 | .enter = pxa3xx_cpu_pm_enter, |
398 | }; | 202 | }; |
@@ -580,6 +384,22 @@ void __init pxa3xx_init_irq(void) | |||
580 | pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); | 384 | pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); |
581 | } | 385 | } |
582 | 386 | ||
387 | static struct map_desc pxa3xx_io_desc[] __initdata = { | ||
388 | { /* Mem Ctl */ | ||
389 | .virtual = SMEMC_VIRT, | ||
390 | .pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE), | ||
391 | .length = 0x00200000, | ||
392 | .type = MT_DEVICE | ||
393 | } | ||
394 | }; | ||
395 | |||
396 | void __init pxa3xx_map_io(void) | ||
397 | { | ||
398 | pxa_map_io(); | ||
399 | iotable_init(ARRAY_AND_SIZE(pxa3xx_io_desc)); | ||
400 | pxa3xx_get_clk_frequency_khz(1); | ||
401 | } | ||
402 | |||
583 | /* | 403 | /* |
584 | * device registration specific to PXA3xx. | 404 | * device registration specific to PXA3xx. |
585 | */ | 405 | */ |
@@ -615,7 +435,9 @@ static struct sys_device pxa3xx_sysdev[] = { | |||
615 | .cls = &pxa3xx_mfp_sysclass, | 435 | .cls = &pxa3xx_mfp_sysclass, |
616 | }, { | 436 | }, { |
617 | .cls = &pxa_gpio_sysclass, | 437 | .cls = &pxa_gpio_sysclass, |
618 | }, | 438 | }, { |
439 | .cls = &pxa3xx_clock_sysclass, | ||
440 | } | ||
619 | }; | 441 | }; |
620 | 442 | ||
621 | static int __init pxa3xx_init(void) | 443 | static int __init pxa3xx_init(void) |
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c index 7d29dd3af79d..8aeacf908784 100644 --- a/arch/arm/mach-pxa/pxa930.c +++ b/arch/arm/mach-pxa/pxa930.c | |||
@@ -192,7 +192,7 @@ static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = { | |||
192 | 192 | ||
193 | static int __init pxa930_init(void) | 193 | static int __init pxa930_init(void) |
194 | { | 194 | { |
195 | if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) { | 195 | if (cpu_is_pxa93x()) { |
196 | mfp_init_base(io_p2v(MFPR_BASE)); | 196 | mfp_init_base(io_p2v(MFPR_BASE)); |
197 | mfp_init_addr(pxa930_mfp_addr_map); | 197 | mfp_init_addr(pxa930_mfp_addr_map); |
198 | } | 198 | } |
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c new file mode 100644 index 000000000000..437980f72710 --- /dev/null +++ b/arch/arm/mach-pxa/pxa95x.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/pxa95x.c | ||
3 | * | ||
4 | * code specific to PXA95x aka MGx | ||
5 | * | ||
6 | * Copyright (C) 2009-2010 Marvell International Ltd. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/sysdev.h> | ||
21 | |||
22 | #include <mach/hardware.h> | ||
23 | #include <mach/gpio.h> | ||
24 | #include <mach/pxa3xx-regs.h> | ||
25 | #include <mach/pxa930.h> | ||
26 | #include <mach/reset.h> | ||
27 | #include <mach/pm.h> | ||
28 | #include <mach/dma.h> | ||
29 | #include <mach/regs-intc.h> | ||
30 | #include <plat/i2c.h> | ||
31 | |||
32 | #include "generic.h" | ||
33 | #include "devices.h" | ||
34 | #include "clock.h" | ||
35 | |||
36 | static struct mfp_addr_map pxa95x_mfp_addr_map[] __initdata = { | ||
37 | |||
38 | MFP_ADDR(GPIO0, 0x02e0), | ||
39 | MFP_ADDR(GPIO1, 0x02dc), | ||
40 | MFP_ADDR(GPIO2, 0x02e8), | ||
41 | MFP_ADDR(GPIO3, 0x02d8), | ||
42 | MFP_ADDR(GPIO4, 0x02e4), | ||
43 | MFP_ADDR(GPIO5, 0x02ec), | ||
44 | MFP_ADDR(GPIO6, 0x02f8), | ||
45 | MFP_ADDR(GPIO7, 0x02fc), | ||
46 | MFP_ADDR(GPIO8, 0x0300), | ||
47 | MFP_ADDR(GPIO9, 0x02d4), | ||
48 | MFP_ADDR(GPIO10, 0x02f4), | ||
49 | MFP_ADDR(GPIO11, 0x02f0), | ||
50 | MFP_ADDR(GPIO12, 0x0304), | ||
51 | MFP_ADDR(GPIO13, 0x0310), | ||
52 | MFP_ADDR(GPIO14, 0x0308), | ||
53 | MFP_ADDR(GPIO15, 0x030c), | ||
54 | MFP_ADDR(GPIO16, 0x04e8), | ||
55 | MFP_ADDR(GPIO17, 0x04f4), | ||
56 | MFP_ADDR(GPIO18, 0x04f8), | ||
57 | MFP_ADDR(GPIO19, 0x04fc), | ||
58 | MFP_ADDR(GPIO20, 0x0518), | ||
59 | MFP_ADDR(GPIO21, 0x051c), | ||
60 | MFP_ADDR(GPIO22, 0x04ec), | ||
61 | MFP_ADDR(GPIO23, 0x0500), | ||
62 | MFP_ADDR(GPIO24, 0x04f0), | ||
63 | MFP_ADDR(GPIO25, 0x0504), | ||
64 | MFP_ADDR(GPIO26, 0x0510), | ||
65 | MFP_ADDR(GPIO27, 0x0514), | ||
66 | MFP_ADDR(GPIO28, 0x0520), | ||
67 | MFP_ADDR(GPIO29, 0x0600), | ||
68 | MFP_ADDR(GPIO30, 0x0618), | ||
69 | MFP_ADDR(GPIO31, 0x0610), | ||
70 | MFP_ADDR(GPIO32, 0x060c), | ||
71 | MFP_ADDR(GPIO33, 0x061c), | ||
72 | MFP_ADDR(GPIO34, 0x0620), | ||
73 | MFP_ADDR(GPIO35, 0x0628), | ||
74 | MFP_ADDR(GPIO36, 0x062c), | ||
75 | MFP_ADDR(GPIO37, 0x0630), | ||
76 | MFP_ADDR(GPIO38, 0x0634), | ||
77 | MFP_ADDR(GPIO39, 0x0638), | ||
78 | MFP_ADDR(GPIO40, 0x063c), | ||
79 | MFP_ADDR(GPIO41, 0x0614), | ||
80 | MFP_ADDR(GPIO42, 0x0624), | ||
81 | MFP_ADDR(GPIO43, 0x0608), | ||
82 | MFP_ADDR(GPIO44, 0x0604), | ||
83 | MFP_ADDR(GPIO45, 0x050c), | ||
84 | MFP_ADDR(GPIO46, 0x0508), | ||
85 | MFP_ADDR(GPIO47, 0x02bc), | ||
86 | MFP_ADDR(GPIO48, 0x02b4), | ||
87 | MFP_ADDR(GPIO49, 0x02b8), | ||
88 | MFP_ADDR(GPIO50, 0x02c8), | ||
89 | MFP_ADDR(GPIO51, 0x02c0), | ||
90 | MFP_ADDR(GPIO52, 0x02c4), | ||
91 | MFP_ADDR(GPIO53, 0x02d0), | ||
92 | MFP_ADDR(GPIO54, 0x02cc), | ||
93 | MFP_ADDR(GPIO55, 0x029c), | ||
94 | MFP_ADDR(GPIO56, 0x02a0), | ||
95 | MFP_ADDR(GPIO57, 0x0294), | ||
96 | MFP_ADDR(GPIO58, 0x0298), | ||
97 | MFP_ADDR(GPIO59, 0x02a4), | ||
98 | MFP_ADDR(GPIO60, 0x02a8), | ||
99 | MFP_ADDR(GPIO61, 0x02b0), | ||
100 | MFP_ADDR(GPIO62, 0x02ac), | ||
101 | MFP_ADDR(GPIO63, 0x0640), | ||
102 | MFP_ADDR(GPIO64, 0x065c), | ||
103 | MFP_ADDR(GPIO65, 0x0648), | ||
104 | MFP_ADDR(GPIO66, 0x0644), | ||
105 | MFP_ADDR(GPIO67, 0x0674), | ||
106 | MFP_ADDR(GPIO68, 0x0658), | ||
107 | MFP_ADDR(GPIO69, 0x0654), | ||
108 | MFP_ADDR(GPIO70, 0x0660), | ||
109 | MFP_ADDR(GPIO71, 0x0668), | ||
110 | MFP_ADDR(GPIO72, 0x0664), | ||
111 | MFP_ADDR(GPIO73, 0x0650), | ||
112 | MFP_ADDR(GPIO74, 0x066c), | ||
113 | MFP_ADDR(GPIO75, 0x064c), | ||
114 | MFP_ADDR(GPIO76, 0x0670), | ||
115 | MFP_ADDR(GPIO77, 0x0678), | ||
116 | MFP_ADDR(GPIO78, 0x067c), | ||
117 | MFP_ADDR(GPIO79, 0x0694), | ||
118 | MFP_ADDR(GPIO80, 0x069c), | ||
119 | MFP_ADDR(GPIO81, 0x06a0), | ||
120 | MFP_ADDR(GPIO82, 0x06a4), | ||
121 | MFP_ADDR(GPIO83, 0x0698), | ||
122 | MFP_ADDR(GPIO84, 0x06bc), | ||
123 | MFP_ADDR(GPIO85, 0x06b4), | ||
124 | MFP_ADDR(GPIO86, 0x06b0), | ||
125 | MFP_ADDR(GPIO87, 0x06c0), | ||
126 | MFP_ADDR(GPIO88, 0x06c4), | ||
127 | MFP_ADDR(GPIO89, 0x06ac), | ||
128 | MFP_ADDR(GPIO90, 0x0680), | ||
129 | MFP_ADDR(GPIO91, 0x0684), | ||
130 | MFP_ADDR(GPIO92, 0x0688), | ||
131 | MFP_ADDR(GPIO93, 0x0690), | ||
132 | MFP_ADDR(GPIO94, 0x068c), | ||
133 | MFP_ADDR(GPIO95, 0x06a8), | ||
134 | MFP_ADDR(GPIO96, 0x06b8), | ||
135 | MFP_ADDR(GPIO97, 0x0410), | ||
136 | MFP_ADDR(GPIO98, 0x0418), | ||
137 | MFP_ADDR(GPIO99, 0x041c), | ||
138 | MFP_ADDR(GPIO100, 0x0414), | ||
139 | MFP_ADDR(GPIO101, 0x0408), | ||
140 | MFP_ADDR(GPIO102, 0x0324), | ||
141 | MFP_ADDR(GPIO103, 0x040c), | ||
142 | MFP_ADDR(GPIO104, 0x0400), | ||
143 | MFP_ADDR(GPIO105, 0x0328), | ||
144 | MFP_ADDR(GPIO106, 0x0404), | ||
145 | |||
146 | MFP_ADDR(GPIO159, 0x0524), | ||
147 | MFP_ADDR(GPIO163, 0x0534), | ||
148 | MFP_ADDR(GPIO167, 0x0544), | ||
149 | MFP_ADDR(GPIO168, 0x0548), | ||
150 | MFP_ADDR(GPIO169, 0x054c), | ||
151 | MFP_ADDR(GPIO170, 0x0550), | ||
152 | MFP_ADDR(GPIO171, 0x0554), | ||
153 | MFP_ADDR(GPIO172, 0x0558), | ||
154 | MFP_ADDR(GPIO173, 0x055c), | ||
155 | |||
156 | MFP_ADDR(nXCVREN, 0x0204), | ||
157 | MFP_ADDR(DF_CLE_nOE, 0x020c), | ||
158 | MFP_ADDR(DF_nADV1_ALE, 0x0218), | ||
159 | MFP_ADDR(DF_SCLK_E, 0x0214), | ||
160 | MFP_ADDR(DF_SCLK_S, 0x0210), | ||
161 | MFP_ADDR(nBE0, 0x021c), | ||
162 | MFP_ADDR(nBE1, 0x0220), | ||
163 | MFP_ADDR(DF_nADV2_ALE, 0x0224), | ||
164 | MFP_ADDR(DF_INT_RnB, 0x0228), | ||
165 | MFP_ADDR(DF_nCS0, 0x022c), | ||
166 | MFP_ADDR(DF_nCS1, 0x0230), | ||
167 | MFP_ADDR(nLUA, 0x0254), | ||
168 | MFP_ADDR(nLLA, 0x0258), | ||
169 | MFP_ADDR(DF_nWE, 0x0234), | ||
170 | MFP_ADDR(DF_nRE_nOE, 0x0238), | ||
171 | MFP_ADDR(DF_ADDR0, 0x024c), | ||
172 | MFP_ADDR(DF_ADDR1, 0x0250), | ||
173 | MFP_ADDR(DF_ADDR2, 0x025c), | ||
174 | MFP_ADDR(DF_ADDR3, 0x0260), | ||
175 | MFP_ADDR(DF_IO0, 0x023c), | ||
176 | MFP_ADDR(DF_IO1, 0x0240), | ||
177 | MFP_ADDR(DF_IO2, 0x0244), | ||
178 | MFP_ADDR(DF_IO3, 0x0248), | ||
179 | MFP_ADDR(DF_IO4, 0x0264), | ||
180 | MFP_ADDR(DF_IO5, 0x0268), | ||
181 | MFP_ADDR(DF_IO6, 0x026c), | ||
182 | MFP_ADDR(DF_IO7, 0x0270), | ||
183 | MFP_ADDR(DF_IO8, 0x0274), | ||
184 | MFP_ADDR(DF_IO9, 0x0278), | ||
185 | MFP_ADDR(DF_IO10, 0x027c), | ||
186 | MFP_ADDR(DF_IO11, 0x0280), | ||
187 | MFP_ADDR(DF_IO12, 0x0284), | ||
188 | MFP_ADDR(DF_IO13, 0x0288), | ||
189 | MFP_ADDR(DF_IO14, 0x028c), | ||
190 | MFP_ADDR(DF_IO15, 0x0290), | ||
191 | |||
192 | MFP_ADDR(GSIM_UIO, 0x0314), | ||
193 | MFP_ADDR(GSIM_UCLK, 0x0318), | ||
194 | MFP_ADDR(GSIM_UDET, 0x031c), | ||
195 | MFP_ADDR(GSIM_nURST, 0x0320), | ||
196 | |||
197 | MFP_ADDR(PMIC_INT, 0x06c8), | ||
198 | |||
199 | MFP_ADDR(RDY, 0x0200), | ||
200 | |||
201 | MFP_ADDR_END, | ||
202 | }; | ||
203 | |||
204 | static DEFINE_CK(pxa95x_lcd, LCD, &clk_pxa3xx_hsio_ops); | ||
205 | static DEFINE_CLK(pxa95x_pout, &clk_pxa3xx_pout_ops, 13000000, 70); | ||
206 | static DEFINE_PXA3_CKEN(pxa95x_ffuart, FFUART, 14857000, 1); | ||
207 | static DEFINE_PXA3_CKEN(pxa95x_btuart, BTUART, 14857000, 1); | ||
208 | static DEFINE_PXA3_CKEN(pxa95x_stuart, STUART, 14857000, 1); | ||
209 | static DEFINE_PXA3_CKEN(pxa95x_i2c, I2C, 32842000, 0); | ||
210 | static DEFINE_PXA3_CKEN(pxa95x_keypad, KEYPAD, 32768, 0); | ||
211 | static DEFINE_PXA3_CKEN(pxa95x_ssp1, SSP1, 13000000, 0); | ||
212 | static DEFINE_PXA3_CKEN(pxa95x_ssp2, SSP2, 13000000, 0); | ||
213 | static DEFINE_PXA3_CKEN(pxa95x_ssp3, SSP3, 13000000, 0); | ||
214 | static DEFINE_PXA3_CKEN(pxa95x_ssp4, SSP4, 13000000, 0); | ||
215 | static DEFINE_PXA3_CKEN(pxa95x_pwm0, PWM0, 13000000, 0); | ||
216 | static DEFINE_PXA3_CKEN(pxa95x_pwm1, PWM1, 13000000, 0); | ||
217 | |||
218 | static struct clk_lookup pxa95x_clkregs[] = { | ||
219 | INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"), | ||
220 | /* Power I2C clock is always on */ | ||
221 | INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), | ||
222 | INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL), | ||
223 | INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL), | ||
224 | INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL), | ||
225 | INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-uart.2", NULL), | ||
226 | INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-ir", "UARTCLK"), | ||
227 | INIT_CLKREG(&clk_pxa95x_i2c, "pxa2xx-i2c.0", NULL), | ||
228 | INIT_CLKREG(&clk_pxa95x_keypad, "pxa27x-keypad", NULL), | ||
229 | INIT_CLKREG(&clk_pxa95x_ssp1, "pxa27x-ssp.0", NULL), | ||
230 | INIT_CLKREG(&clk_pxa95x_ssp2, "pxa27x-ssp.1", NULL), | ||
231 | INIT_CLKREG(&clk_pxa95x_ssp3, "pxa27x-ssp.2", NULL), | ||
232 | INIT_CLKREG(&clk_pxa95x_ssp4, "pxa27x-ssp.3", NULL), | ||
233 | INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL), | ||
234 | INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL), | ||
235 | }; | ||
236 | |||
237 | void __init pxa95x_init_irq(void) | ||
238 | { | ||
239 | pxa_init_irq(96, NULL); | ||
240 | pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL); | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * device registration specific to PXA93x. | ||
245 | */ | ||
246 | |||
247 | void __init pxa95x_set_i2c_power_info(struct i2c_pxa_platform_data *info) | ||
248 | { | ||
249 | pxa_register_device(&pxa3xx_device_i2c_power, info); | ||
250 | } | ||
251 | |||
252 | static struct platform_device *devices[] __initdata = { | ||
253 | &sa1100_device_rtc, | ||
254 | &pxa_device_rtc, | ||
255 | &pxa27x_device_ssp1, | ||
256 | &pxa27x_device_ssp2, | ||
257 | &pxa27x_device_ssp3, | ||
258 | &pxa3xx_device_ssp4, | ||
259 | &pxa27x_device_pwm0, | ||
260 | &pxa27x_device_pwm1, | ||
261 | }; | ||
262 | |||
263 | static struct sys_device pxa95x_sysdev[] = { | ||
264 | { | ||
265 | .cls = &pxa_irq_sysclass, | ||
266 | }, { | ||
267 | .cls = &pxa_gpio_sysclass, | ||
268 | }, { | ||
269 | .cls = &pxa3xx_clock_sysclass, | ||
270 | } | ||
271 | }; | ||
272 | |||
273 | static int __init pxa95x_init(void) | ||
274 | { | ||
275 | int ret = 0, i; | ||
276 | |||
277 | if (cpu_is_pxa95x()) { | ||
278 | mfp_init_base(io_p2v(MFPR_BASE)); | ||
279 | mfp_init_addr(pxa95x_mfp_addr_map); | ||
280 | |||
281 | reset_status = ARSR; | ||
282 | |||
283 | /* | ||
284 | * clear RDH bit every time after reset | ||
285 | * | ||
286 | * Note: the last 3 bits DxS are write-1-to-clear so carefully | ||
287 | * preserve them here in case they will be referenced later | ||
288 | */ | ||
289 | ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S); | ||
290 | |||
291 | clkdev_add_table(pxa95x_clkregs, ARRAY_SIZE(pxa95x_clkregs)); | ||
292 | |||
293 | if ((ret = pxa_init_dma(IRQ_DMA, 32))) | ||
294 | return ret; | ||
295 | |||
296 | for (i = 0; i < ARRAY_SIZE(pxa95x_sysdev); i++) { | ||
297 | ret = sysdev_register(&pxa95x_sysdev[i]); | ||
298 | if (ret) | ||
299 | pr_err("failed to register sysdev[%d]\n", i); | ||
300 | } | ||
301 | |||
302 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
303 | } | ||
304 | |||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | postcore_initcall(pxa95x_init); | ||
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 4121d03ea2c3..8361151be054 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c | |||
@@ -588,6 +588,9 @@ static struct pxafb_mach_info raumfeld_sharp_lcd_info = { | |||
588 | .num_modes = 1, | 588 | .num_modes = 1, |
589 | .video_mem_size = 0x400000, | 589 | .video_mem_size = 0x400000, |
590 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, | 590 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, |
591 | #ifdef CONFIG_PXA3XX_GCU | ||
592 | .acceleration_enabled = 1, | ||
593 | #endif | ||
591 | }; | 594 | }; |
592 | 595 | ||
593 | static void __init raumfeld_lcd_init(void) | 596 | static void __init raumfeld_lcd_init(void) |
@@ -616,6 +619,8 @@ static void __init raumfeld_lcd_init(void) | |||
616 | pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n"); | 619 | pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n"); |
617 | else | 620 | else |
618 | gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); | 621 | gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); |
622 | |||
623 | platform_device_register(&pxa3xx_device_gcu); | ||
619 | } | 624 | } |
620 | 625 | ||
621 | /** | 626 | /** |
@@ -1085,7 +1090,7 @@ static void __init raumfeld_speaker_init(void) | |||
1085 | MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") | 1090 | MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") |
1086 | .boot_params = RAUMFELD_SDRAM_BASE + 0x100, | 1091 | .boot_params = RAUMFELD_SDRAM_BASE + 0x100, |
1087 | .init_machine = raumfeld_controller_init, | 1092 | .init_machine = raumfeld_controller_init, |
1088 | .map_io = pxa_map_io, | 1093 | .map_io = pxa3xx_map_io, |
1089 | .init_irq = pxa3xx_init_irq, | 1094 | .init_irq = pxa3xx_init_irq, |
1090 | .timer = &pxa_timer, | 1095 | .timer = &pxa_timer, |
1091 | MACHINE_END | 1096 | MACHINE_END |
@@ -1095,7 +1100,7 @@ MACHINE_END | |||
1095 | MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") | 1100 | MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") |
1096 | .boot_params = RAUMFELD_SDRAM_BASE + 0x100, | 1101 | .boot_params = RAUMFELD_SDRAM_BASE + 0x100, |
1097 | .init_machine = raumfeld_connector_init, | 1102 | .init_machine = raumfeld_connector_init, |
1098 | .map_io = pxa_map_io, | 1103 | .map_io = pxa3xx_map_io, |
1099 | .init_irq = pxa3xx_init_irq, | 1104 | .init_irq = pxa3xx_init_irq, |
1100 | .timer = &pxa_timer, | 1105 | .timer = &pxa_timer, |
1101 | MACHINE_END | 1106 | MACHINE_END |
@@ -1105,7 +1110,7 @@ MACHINE_END | |||
1105 | MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") | 1110 | MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") |
1106 | .boot_params = RAUMFELD_SDRAM_BASE + 0x100, | 1111 | .boot_params = RAUMFELD_SDRAM_BASE + 0x100, |
1107 | .init_machine = raumfeld_speaker_init, | 1112 | .init_machine = raumfeld_speaker_init, |
1108 | .map_io = pxa_map_io, | 1113 | .map_io = pxa3xx_map_io, |
1109 | .init_irq = pxa3xx_init_irq, | 1114 | .init_irq = pxa3xx_init_irq, |
1110 | .timer = &pxa_timer, | 1115 | .timer = &pxa_timer, |
1111 | MACHINE_END | 1116 | MACHINE_END |
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index ffa50e633ee6..c1ca8cb467fc 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c | |||
@@ -597,7 +597,7 @@ static void __init saar_init(void) | |||
597 | MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)") | 597 | MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)") |
598 | /* Maintainer: Eric Miao <eric.miao@marvell.com> */ | 598 | /* Maintainer: Eric Miao <eric.miao@marvell.com> */ |
599 | .boot_params = 0xa0000100, | 599 | .boot_params = 0xa0000100, |
600 | .map_io = pxa_map_io, | 600 | .map_io = pxa3xx_map_io, |
601 | .init_irq = pxa3xx_init_irq, | 601 | .init_irq = pxa3xx_init_irq, |
602 | .timer = &pxa_timer, | 602 | .timer = &pxa_timer, |
603 | .init_machine = saar_init, | 603 | .init_machine = saar_init, |
diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c new file mode 100644 index 000000000000..e497922f761a --- /dev/null +++ b/arch/arm/mach-pxa/saarb.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/saarb.c | ||
3 | * | ||
4 | * Support for the Marvell Handheld Platform (aka SAARB) | ||
5 | * | ||
6 | * Copyright (C) 2007-2010 Marvell International Ltd. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * publishhed by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/mfd/88pm860x.h> | ||
17 | |||
18 | #include <asm/mach-types.h> | ||
19 | #include <asm/mach/arch.h> | ||
20 | |||
21 | #include <mach/irqs.h> | ||
22 | #include <mach/hardware.h> | ||
23 | #include <mach/mfp.h> | ||
24 | #include <mach/mfp-pxa930.h> | ||
25 | #include <mach/gpio.h> | ||
26 | |||
27 | #include <plat/i2c.h> | ||
28 | |||
29 | #include "generic.h" | ||
30 | |||
31 | #define SAARB_NR_IRQS (IRQ_BOARD_START + 40) | ||
32 | |||
33 | static struct pm860x_touch_pdata saarb_touch = { | ||
34 | .gpadc_prebias = 1, | ||
35 | .slot_cycle = 1, | ||
36 | .tsi_prebias = 6, | ||
37 | .pen_prebias = 16, | ||
38 | .pen_prechg = 2, | ||
39 | .res_x = 300, | ||
40 | }; | ||
41 | |||
42 | static struct pm860x_backlight_pdata saarb_backlight[] = { | ||
43 | { | ||
44 | .id = PM8606_ID_BACKLIGHT, | ||
45 | .iset = PM8606_WLED_CURRENT(24), | ||
46 | .flags = PM8606_BACKLIGHT1, | ||
47 | }, | ||
48 | {}, | ||
49 | }; | ||
50 | |||
51 | static struct pm860x_led_pdata saarb_led[] = { | ||
52 | { | ||
53 | .id = PM8606_ID_LED, | ||
54 | .iset = PM8606_LED_CURRENT(12), | ||
55 | .flags = PM8606_LED1_RED, | ||
56 | }, { | ||
57 | .id = PM8606_ID_LED, | ||
58 | .iset = PM8606_LED_CURRENT(12), | ||
59 | .flags = PM8606_LED1_GREEN, | ||
60 | }, { | ||
61 | .id = PM8606_ID_LED, | ||
62 | .iset = PM8606_LED_CURRENT(12), | ||
63 | .flags = PM8606_LED1_BLUE, | ||
64 | }, { | ||
65 | .id = PM8606_ID_LED, | ||
66 | .iset = PM8606_LED_CURRENT(12), | ||
67 | .flags = PM8606_LED2_RED, | ||
68 | }, { | ||
69 | .id = PM8606_ID_LED, | ||
70 | .iset = PM8606_LED_CURRENT(12), | ||
71 | .flags = PM8606_LED2_GREEN, | ||
72 | }, { | ||
73 | .id = PM8606_ID_LED, | ||
74 | .iset = PM8606_LED_CURRENT(12), | ||
75 | .flags = PM8606_LED2_BLUE, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | static struct pm860x_platform_data saarb_pm8607_info = { | ||
80 | .touch = &saarb_touch, | ||
81 | .backlight = &saarb_backlight[0], | ||
82 | .led = &saarb_led[0], | ||
83 | .companion_addr = 0x10, | ||
84 | .irq_mode = 0, | ||
85 | .irq_base = IRQ_BOARD_START, | ||
86 | |||
87 | .i2c_port = GI2C_PORT, | ||
88 | }; | ||
89 | |||
90 | static struct i2c_board_info saarb_i2c_info[] = { | ||
91 | { | ||
92 | .type = "88PM860x", | ||
93 | .addr = 0x34, | ||
94 | .platform_data = &saarb_pm8607_info, | ||
95 | .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | static void __init saarb_init(void) | ||
100 | { | ||
101 | pxa_set_ffuart_info(NULL); | ||
102 | pxa_set_i2c_info(NULL); | ||
103 | i2c_register_board_info(0, ARRAY_AND_SIZE(saarb_i2c_info)); | ||
104 | } | ||
105 | |||
106 | MACHINE_START(SAARB, "PXA955 Handheld Platform (aka SAARB)") | ||
107 | .boot_params = 0xa0000100, | ||
108 | .map_io = pxa_map_io, | ||
109 | .nr_irqs = SAARB_NR_IRQS, | ||
110 | .init_irq = pxa95x_init_irq, | ||
111 | .timer = &pxa_timer, | ||
112 | .init_machine = saarb_init, | ||
113 | MACHINE_END | ||
114 | |||
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 52c30b01a671..2f5b08aeb52e 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
15 | #include <asm/assembler.h> | 15 | #include <asm/assembler.h> |
16 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
17 | 17 | #include <mach/smemc.h> | |
18 | #include <mach/pxa2xx-regs.h> | 18 | #include <mach/pxa2xx-regs.h> |
19 | 19 | ||
20 | #define MDREFR_KDIV 0x200a4000 // all banks | 20 | #define MDREFR_KDIV 0x200a4000 // all banks |
diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c index d6f6904132a6..232b7316ec08 100644 --- a/arch/arm/mach-pxa/smemc.c +++ b/arch/arm/mach-pxa/smemc.c | |||
@@ -9,50 +9,37 @@ | |||
9 | #include <linux/sysdev.h> | 9 | #include <linux/sysdev.h> |
10 | 10 | ||
11 | #include <mach/hardware.h> | 11 | #include <mach/hardware.h> |
12 | 12 | #include <mach/smemc.h> | |
13 | #define SMEMC_PHYS_BASE (0x4A000000) | ||
14 | #define SMEMC_PHYS_SIZE (0x90) | ||
15 | |||
16 | #define MSC0 (0x08) /* Static Memory Controller Register 0 */ | ||
17 | #define MSC1 (0x0C) /* Static Memory Controller Register 1 */ | ||
18 | #define SXCNFG (0x1C) /* Synchronous Static Memory Control Register */ | ||
19 | #define MEMCLKCFG (0x68) /* Clock Configuration */ | ||
20 | #define CSADRCFG0 (0x80) /* Address Configuration Register for CS0 */ | ||
21 | #define CSADRCFG1 (0x84) /* Address Configuration Register for CS1 */ | ||
22 | #define CSADRCFG2 (0x88) /* Address Configuration Register for CS2 */ | ||
23 | #define CSADRCFG3 (0x8C) /* Address Configuration Register for CS3 */ | ||
24 | 13 | ||
25 | #ifdef CONFIG_PM | 14 | #ifdef CONFIG_PM |
26 | static void __iomem *smemc_mmio_base; | ||
27 | |||
28 | static unsigned long msc[2]; | 15 | static unsigned long msc[2]; |
29 | static unsigned long sxcnfg, memclkcfg; | 16 | static unsigned long sxcnfg, memclkcfg; |
30 | static unsigned long csadrcfg[4]; | 17 | static unsigned long csadrcfg[4]; |
31 | 18 | ||
32 | static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state) | 19 | static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state) |
33 | { | 20 | { |
34 | msc[0] = __raw_readl(smemc_mmio_base + MSC0); | 21 | msc[0] = __raw_readl(MSC0); |
35 | msc[1] = __raw_readl(smemc_mmio_base + MSC1); | 22 | msc[1] = __raw_readl(MSC1); |
36 | sxcnfg = __raw_readl(smemc_mmio_base + SXCNFG); | 23 | sxcnfg = __raw_readl(SXCNFG); |
37 | memclkcfg = __raw_readl(smemc_mmio_base + MEMCLKCFG); | 24 | memclkcfg = __raw_readl(MEMCLKCFG); |
38 | csadrcfg[0] = __raw_readl(smemc_mmio_base + CSADRCFG0); | 25 | csadrcfg[0] = __raw_readl(CSADRCFG0); |
39 | csadrcfg[1] = __raw_readl(smemc_mmio_base + CSADRCFG1); | 26 | csadrcfg[1] = __raw_readl(CSADRCFG1); |
40 | csadrcfg[2] = __raw_readl(smemc_mmio_base + CSADRCFG2); | 27 | csadrcfg[2] = __raw_readl(CSADRCFG2); |
41 | csadrcfg[3] = __raw_readl(smemc_mmio_base + CSADRCFG3); | 28 | csadrcfg[3] = __raw_readl(CSADRCFG3); |
42 | 29 | ||
43 | return 0; | 30 | return 0; |
44 | } | 31 | } |
45 | 32 | ||
46 | static int pxa3xx_smemc_resume(struct sys_device *dev) | 33 | static int pxa3xx_smemc_resume(struct sys_device *dev) |
47 | { | 34 | { |
48 | __raw_writel(msc[0], smemc_mmio_base + MSC0); | 35 | __raw_writel(msc[0], MSC0); |
49 | __raw_writel(msc[1], smemc_mmio_base + MSC1); | 36 | __raw_writel(msc[1], MSC1); |
50 | __raw_writel(sxcnfg, smemc_mmio_base + SXCNFG); | 37 | __raw_writel(sxcnfg, SXCNFG); |
51 | __raw_writel(memclkcfg, smemc_mmio_base + MEMCLKCFG); | 38 | __raw_writel(memclkcfg, MEMCLKCFG); |
52 | __raw_writel(csadrcfg[0], smemc_mmio_base + CSADRCFG0); | 39 | __raw_writel(csadrcfg[0], CSADRCFG0); |
53 | __raw_writel(csadrcfg[1], smemc_mmio_base + CSADRCFG1); | 40 | __raw_writel(csadrcfg[1], CSADRCFG1); |
54 | __raw_writel(csadrcfg[2], smemc_mmio_base + CSADRCFG2); | 41 | __raw_writel(csadrcfg[2], CSADRCFG2); |
55 | __raw_writel(csadrcfg[3], smemc_mmio_base + CSADRCFG3); | 42 | __raw_writel(csadrcfg[3], CSADRCFG3); |
56 | 43 | ||
57 | return 0; | 44 | return 0; |
58 | } | 45 | } |
@@ -73,10 +60,6 @@ static int __init smemc_init(void) | |||
73 | int ret = 0; | 60 | int ret = 0; |
74 | 61 | ||
75 | if (cpu_is_pxa3xx()) { | 62 | if (cpu_is_pxa3xx()) { |
76 | smemc_mmio_base = ioremap(SMEMC_PHYS_BASE, SMEMC_PHYS_SIZE); | ||
77 | if (smemc_mmio_base == NULL) | ||
78 | return -ENODEV; | ||
79 | |||
80 | ret = sysdev_class_register(&smemc_sysclass); | 63 | ret = sysdev_class_register(&smemc_sysclass); |
81 | if (ret) | 64 | if (ret) |
82 | return ret; | 65 | return ret; |
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index f736119f1ebf..0499a69e7673 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/mtd/sharpsl.h> | 27 | #include <linux/mtd/sharpsl.h> |
28 | #include <linux/input/matrix_keypad.h> | 28 | #include <linux/input/matrix_keypad.h> |
29 | #include <linux/regulator/machine.h> | 29 | #include <linux/regulator/machine.h> |
30 | #include <linux/io.h> | ||
30 | 31 | ||
31 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
32 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
@@ -44,6 +45,7 @@ | |||
44 | #include <mach/pxa2xx_spi.h> | 45 | #include <mach/pxa2xx_spi.h> |
45 | #include <mach/spitz.h> | 46 | #include <mach/spitz.h> |
46 | #include <mach/sharpsl_pm.h> | 47 | #include <mach/sharpsl_pm.h> |
48 | #include <mach/smemc.h> | ||
47 | 49 | ||
48 | #include <plat/i2c.h> | 50 | #include <plat/i2c.h> |
49 | 51 | ||
@@ -929,9 +931,10 @@ static void spitz_poweroff(void) | |||
929 | 931 | ||
930 | static void spitz_restart(char mode, const char *cmd) | 932 | static void spitz_restart(char mode, const char *cmd) |
931 | { | 933 | { |
934 | uint32_t msc0 = __raw_readl(MSC0); | ||
932 | /* Bootloader magic for a reboot */ | 935 | /* Bootloader magic for a reboot */ |
933 | if ((MSC0 & 0xffff0000) == 0x7ff00000) | 936 | if ((msc0 & 0xffff0000) == 0x7ff00000) |
934 | MSC0 = (MSC0 & 0xffff) | 0x7ee00000; | 937 | __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0); |
935 | 938 | ||
936 | spitz_poweroff(); | 939 | spitz_poweroff(); |
937 | } | 940 | } |
@@ -980,7 +983,7 @@ static void __init spitz_fixup(struct machine_desc *desc, | |||
980 | #ifdef CONFIG_MACH_SPITZ | 983 | #ifdef CONFIG_MACH_SPITZ |
981 | MACHINE_START(SPITZ, "SHARP Spitz") | 984 | MACHINE_START(SPITZ, "SHARP Spitz") |
982 | .fixup = spitz_fixup, | 985 | .fixup = spitz_fixup, |
983 | .map_io = pxa_map_io, | 986 | .map_io = pxa27x_map_io, |
984 | .init_irq = pxa27x_init_irq, | 987 | .init_irq = pxa27x_init_irq, |
985 | .init_machine = spitz_init, | 988 | .init_machine = spitz_init, |
986 | .timer = &pxa_timer, | 989 | .timer = &pxa_timer, |
@@ -990,7 +993,7 @@ MACHINE_END | |||
990 | #ifdef CONFIG_MACH_BORZOI | 993 | #ifdef CONFIG_MACH_BORZOI |
991 | MACHINE_START(BORZOI, "SHARP Borzoi") | 994 | MACHINE_START(BORZOI, "SHARP Borzoi") |
992 | .fixup = spitz_fixup, | 995 | .fixup = spitz_fixup, |
993 | .map_io = pxa_map_io, | 996 | .map_io = pxa27x_map_io, |
994 | .init_irq = pxa27x_init_irq, | 997 | .init_irq = pxa27x_init_irq, |
995 | .init_machine = spitz_init, | 998 | .init_machine = spitz_init, |
996 | .timer = &pxa_timer, | 999 | .timer = &pxa_timer, |
@@ -1000,7 +1003,7 @@ MACHINE_END | |||
1000 | #ifdef CONFIG_MACH_AKITA | 1003 | #ifdef CONFIG_MACH_AKITA |
1001 | MACHINE_START(AKITA, "SHARP Akita") | 1004 | MACHINE_START(AKITA, "SHARP Akita") |
1002 | .fixup = spitz_fixup, | 1005 | .fixup = spitz_fixup, |
1003 | .map_io = pxa_map_io, | 1006 | .map_io = pxa27x_map_io, |
1004 | .init_irq = pxa27x_init_irq, | 1007 | .init_irq = pxa27x_init_irq, |
1005 | .init_machine = spitz_init, | 1008 | .init_machine = spitz_init, |
1006 | .timer = &pxa_timer, | 1009 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 738adc1773fd..3498a1423943 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <mach/udc.h> | 48 | #include <mach/udc.h> |
49 | #include <mach/pxa2xx_spi.h> | 49 | #include <mach/pxa2xx_spi.h> |
50 | #include <mach/pxa27x-udc.h> | 50 | #include <mach/pxa27x-udc.h> |
51 | #include <mach/smemc.h> | ||
51 | 52 | ||
52 | #include <linux/spi/spi.h> | 53 | #include <linux/spi/spi.h> |
53 | #include <linux/mfd/da903x.h> | 54 | #include <linux/mfd/da903x.h> |
@@ -976,7 +977,7 @@ static void __init stargate2_init(void) | |||
976 | { | 977 | { |
977 | /* This is probably a board specific hack as this must be set | 978 | /* This is probably a board specific hack as this must be set |
978 | prior to connecting the MFP stuff up. */ | 979 | prior to connecting the MFP stuff up. */ |
979 | MECR &= ~MECR_NOS; | 980 | __raw_writel(__raw_readl(MECR) & ~MECR_NOS, MECR); |
980 | 981 | ||
981 | pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config)); | 982 | pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config)); |
982 | 983 | ||
@@ -998,7 +999,7 @@ static void __init stargate2_init(void) | |||
998 | 999 | ||
999 | #ifdef CONFIG_MACH_INTELMOTE2 | 1000 | #ifdef CONFIG_MACH_INTELMOTE2 |
1000 | MACHINE_START(INTELMOTE2, "IMOTE 2") | 1001 | MACHINE_START(INTELMOTE2, "IMOTE 2") |
1001 | .map_io = pxa_map_io, | 1002 | .map_io = pxa27x_map_io, |
1002 | .init_irq = pxa27x_init_irq, | 1003 | .init_irq = pxa27x_init_irq, |
1003 | .timer = &pxa_timer, | 1004 | .timer = &pxa_timer, |
1004 | .init_machine = imote2_init, | 1005 | .init_machine = imote2_init, |
@@ -1008,7 +1009,7 @@ MACHINE_END | |||
1008 | 1009 | ||
1009 | #ifdef CONFIG_MACH_STARGATE2 | 1010 | #ifdef CONFIG_MACH_STARGATE2 |
1010 | MACHINE_START(STARGATE2, "Stargate 2") | 1011 | MACHINE_START(STARGATE2, "Stargate 2") |
1011 | .map_io = pxa_map_io, | 1012 | .map_io = pxa27x_map_io, |
1012 | .nr_irqs = STARGATE_NR_IRQS, | 1013 | .nr_irqs = STARGATE_NR_IRQS, |
1013 | .init_irq = pxa27x_init_irq, | 1014 | .init_irq = pxa27x_init_irq, |
1014 | .timer = &pxa_timer, | 1015 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 2ea7545273ad..9cecf8366db8 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c | |||
@@ -490,7 +490,7 @@ static void __init tavorevb_init(void) | |||
490 | MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)") | 490 | MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)") |
491 | /* Maintainer: Eric Miao <eric.miao@marvell.com> */ | 491 | /* Maintainer: Eric Miao <eric.miao@marvell.com> */ |
492 | .boot_params = 0xa0000100, | 492 | .boot_params = 0xa0000100, |
493 | .map_io = pxa_map_io, | 493 | .map_io = pxa3xx_map_io, |
494 | .init_irq = pxa3xx_init_irq, | 494 | .init_irq = pxa3xx_init_irq, |
495 | .timer = &pxa_timer, | 495 | .timer = &pxa_timer, |
496 | .init_machine = tavorevb_init, | 496 | .init_machine = tavorevb_init, |
diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c index dc3011697bbf..70191a9450eb 100644 --- a/arch/arm/mach-pxa/tavorevb3.c +++ b/arch/arm/mach-pxa/tavorevb3.c | |||
@@ -127,7 +127,7 @@ static void __init evb3_init(void) | |||
127 | 127 | ||
128 | MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)") | 128 | MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)") |
129 | .boot_params = 0xa0000100, | 129 | .boot_params = 0xa0000100, |
130 | .map_io = pxa_map_io, | 130 | .map_io = pxa3xx_map_io, |
131 | .nr_irqs = TAVOREVB3_NR_IRQS, | 131 | .nr_irqs = TAVOREVB3_NR_IRQS, |
132 | .init_irq = pxa3xx_init_irq, | 132 | .init_irq = pxa3xx_init_irq, |
133 | .timer = &pxa_timer, | 133 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 0ee1df49606d..57d61ee9b226 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <mach/tosa_bt.h> | 46 | #include <mach/tosa_bt.h> |
47 | #include <mach/pxa2xx_spi.h> | 47 | #include <mach/pxa2xx_spi.h> |
48 | #include <mach/audio.h> | 48 | #include <mach/audio.h> |
49 | #include <mach/smemc.h> | ||
49 | 50 | ||
50 | #include <asm/mach/arch.h> | 51 | #include <asm/mach/arch.h> |
51 | #include <mach/tosa.h> | 52 | #include <mach/tosa.h> |
@@ -893,9 +894,11 @@ static void tosa_poweroff(void) | |||
893 | 894 | ||
894 | static void tosa_restart(char mode, const char *cmd) | 895 | static void tosa_restart(char mode, const char *cmd) |
895 | { | 896 | { |
897 | uint32_t msc0 = __raw_readl(MSC0); | ||
898 | |||
896 | /* Bootloader magic for a reboot */ | 899 | /* Bootloader magic for a reboot */ |
897 | if((MSC0 & 0xffff0000) == 0x7ff00000) | 900 | if((msc0 & 0xffff0000) == 0x7ff00000) |
898 | MSC0 = (MSC0 & 0xffff) | 0x7ee00000; | 901 | __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0); |
899 | 902 | ||
900 | tosa_poweroff(); | 903 | tosa_poweroff(); |
901 | } | 904 | } |
@@ -953,7 +956,7 @@ static void __init fixup_tosa(struct machine_desc *desc, | |||
953 | 956 | ||
954 | MACHINE_START(TOSA, "SHARP Tosa") | 957 | MACHINE_START(TOSA, "SHARP Tosa") |
955 | .fixup = fixup_tosa, | 958 | .fixup = fixup_tosa, |
956 | .map_io = pxa_map_io, | 959 | .map_io = pxa25x_map_io, |
957 | .nr_irqs = TOSA_NR_IRQS, | 960 | .nr_irqs = TOSA_NR_IRQS, |
958 | .init_irq = pxa25x_init_irq, | 961 | .init_irq = pxa25x_init_irq, |
959 | .init_machine = tosa_init, | 962 | .init_machine = tosa_init, |
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 565d062f51d5..43fc9ca14594 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <mach/mmc.h> | 47 | #include <mach/mmc.h> |
48 | #include <mach/irda.h> | 48 | #include <mach/irda.h> |
49 | #include <mach/ohci.h> | 49 | #include <mach/ohci.h> |
50 | #include <mach/smemc.h> | ||
50 | #include <plat/i2c.h> | 51 | #include <plat/i2c.h> |
51 | 52 | ||
52 | #include "generic.h" | 53 | #include "generic.h" |
@@ -539,10 +540,10 @@ static void __init trizeps4_init(void) | |||
539 | 540 | ||
540 | static void __init trizeps4_map_io(void) | 541 | static void __init trizeps4_map_io(void) |
541 | { | 542 | { |
542 | pxa_map_io(); | 543 | pxa27x_map_io(); |
543 | iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc)); | 544 | iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc)); |
544 | 545 | ||
545 | if ((MSC0 & 0x8) && (BOOT_DEF & 0x1)) { | 546 | if ((__raw_readl(MSC0) & 0x8) && (__raw_readl(BOOT_DEF) & 0x1)) { |
546 | /* if flash is 16 bit wide its a Trizeps4 WL */ | 547 | /* if flash is 16 bit wide its a Trizeps4 WL */ |
547 | __machine_arch_type = MACH_TYPE_TRIZEPS4WL; | 548 | __machine_arch_type = MACH_TYPE_TRIZEPS4WL; |
548 | trizeps4_flash_data[0].width = 2; | 549 | trizeps4_flash_data[0].width = 2; |
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 438fc9a5ed59..de69b203afa7 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c | |||
@@ -983,7 +983,7 @@ static struct map_desc viper_io_desc[] __initdata = { | |||
983 | 983 | ||
984 | static void __init viper_map_io(void) | 984 | static void __init viper_map_io(void) |
985 | { | 985 | { |
986 | pxa_map_io(); | 986 | pxa25x_map_io(); |
987 | 987 | ||
988 | iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc)); | 988 | iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc)); |
989 | 989 | ||
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index f45ac0961778..b9b579715ff6 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c | |||
@@ -719,7 +719,7 @@ static void __init vpac270_init(void) | |||
719 | 719 | ||
720 | MACHINE_START(VPAC270, "Voipac PXA270") | 720 | MACHINE_START(VPAC270, "Voipac PXA270") |
721 | .boot_params = 0xa0000100, | 721 | .boot_params = 0xa0000100, |
722 | .map_io = pxa_map_io, | 722 | .map_io = pxa27x_map_io, |
723 | .init_irq = pxa27x_init_irq, | 723 | .init_irq = pxa27x_init_irq, |
724 | .timer = &pxa_timer, | 724 | .timer = &pxa_timer, |
725 | .init_machine = vpac270_init | 725 | .init_machine = vpac270_init |
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c index 3260ce73d327..51c0281c6e0a 100644 --- a/arch/arm/mach-pxa/xcep.c +++ b/arch/arm/mach-pxa/xcep.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
32 | #include <mach/pxa2xx-regs.h> | 32 | #include <mach/pxa2xx-regs.h> |
33 | #include <mach/mfp-pxa25x.h> | 33 | #include <mach/mfp-pxa25x.h> |
34 | #include <mach/smemc.h> | ||
34 | 35 | ||
35 | #include "generic.h" | 36 | #include "generic.h" |
36 | 37 | ||
@@ -172,9 +173,9 @@ static void __init xcep_init(void) | |||
172 | 173 | ||
173 | /* See Intel XScale Developer's Guide for details */ | 174 | /* See Intel XScale Developer's Guide for details */ |
174 | /* Set RDF and RDN to appropriate values (chip select 3 (smc91x)) */ | 175 | /* Set RDF and RDN to appropriate values (chip select 3 (smc91x)) */ |
175 | MSC1 = (MSC1 & 0xffff) | 0xD5540000; | 176 | __raw_writel((__raw_readl(MSC1) & 0xffff) | 0xD5540000, MSC1); |
176 | /* Set RDF and RDN to appropriate values (chip select 5 (fpga)) */ | 177 | /* Set RDF and RDN to appropriate values (chip select 5 (fpga)) */ |
177 | MSC2 = (MSC2 & 0xffff) | 0x72A00000; | 178 | __raw_writel((__raw_readl(MSC2) & 0xffff) | 0x72A00000, MSC2); |
178 | 179 | ||
179 | platform_add_devices(ARRAY_AND_SIZE(devices)); | 180 | platform_add_devices(ARRAY_AND_SIZE(devices)); |
180 | pxa_set_i2c_info(&xcep_i2c_platform_data); | 181 | pxa_set_i2c_info(&xcep_i2c_platform_data); |
@@ -183,7 +184,7 @@ static void __init xcep_init(void) | |||
183 | MACHINE_START(XCEP, "Iskratel XCEP") | 184 | MACHINE_START(XCEP, "Iskratel XCEP") |
184 | .boot_params = 0xa0000100, | 185 | .boot_params = 0xa0000100, |
185 | .init_machine = xcep_init, | 186 | .init_machine = xcep_init, |
186 | .map_io = pxa_map_io, | 187 | .map_io = pxa25x_map_io, |
187 | .init_irq = pxa25x_init_irq, | 188 | .init_irq = pxa25x_init_irq, |
188 | .timer = &pxa_timer, | 189 | .timer = &pxa_timer, |
189 | MACHINE_END | 190 | MACHINE_END |
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index fefde9848d82..527c2a1ed310 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c | |||
@@ -704,7 +704,7 @@ static void __init z2_init(void) | |||
704 | 704 | ||
705 | MACHINE_START(ZIPIT2, "Zipit Z2") | 705 | MACHINE_START(ZIPIT2, "Zipit Z2") |
706 | .boot_params = 0xa0000100, | 706 | .boot_params = 0xa0000100, |
707 | .map_io = pxa_map_io, | 707 | .map_io = pxa27x_map_io, |
708 | .init_irq = pxa27x_init_irq, | 708 | .init_irq = pxa27x_init_irq, |
709 | .timer = &pxa_timer, | 709 | .timer = &pxa_timer, |
710 | .init_machine = z2_init, | 710 | .init_machine = z2_init, |
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index dea46a2d089b..c87f2b35ee05 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <mach/audio.h> | 47 | #include <mach/audio.h> |
48 | #include <mach/arcom-pcmcia.h> | 48 | #include <mach/arcom-pcmcia.h> |
49 | #include <mach/zeus.h> | 49 | #include <mach/zeus.h> |
50 | #include <mach/smemc.h> | ||
50 | 51 | ||
51 | #include "generic.h" | 52 | #include "generic.h" |
52 | 53 | ||
@@ -823,13 +824,16 @@ static mfp_cfg_t zeus_pin_config[] __initdata = { | |||
823 | static void __init zeus_init(void) | 824 | static void __init zeus_init(void) |
824 | { | 825 | { |
825 | u16 dm9000_msc = DM9K_MSC_VALUE; | 826 | u16 dm9000_msc = DM9K_MSC_VALUE; |
827 | u32 msc0, msc1; | ||
826 | 828 | ||
827 | system_rev = __raw_readw(ZEUS_CPLD_VERSION); | 829 | system_rev = __raw_readw(ZEUS_CPLD_VERSION); |
828 | pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f)); | 830 | pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f)); |
829 | 831 | ||
830 | /* Fix timings for dm9000s (CS1/CS2)*/ | 832 | /* Fix timings for dm9000s (CS1/CS2)*/ |
831 | MSC0 = (MSC0 & 0xffff) | (dm9000_msc << 16); | 833 | msc0 = __raw_readl(MSC0) & 0x0000ffff | (dm9000_msc << 16); |
832 | MSC1 = (MSC1 & 0xffff0000) | dm9000_msc; | 834 | msc1 = __raw_readl(MSC1) & 0xffff0000 | dm9000_msc; |
835 | __raw_writel(msc0, MSC0); | ||
836 | __raw_writel(msc1, MSC1); | ||
833 | 837 | ||
834 | pm_power_off = zeus_power_off; | 838 | pm_power_off = zeus_power_off; |
835 | zeus_setup_apm(); | 839 | zeus_setup_apm(); |
@@ -883,7 +887,7 @@ static struct map_desc zeus_io_desc[] __initdata = { | |||
883 | 887 | ||
884 | static void __init zeus_map_io(void) | 888 | static void __init zeus_map_io(void) |
885 | { | 889 | { |
886 | pxa_map_io(); | 890 | pxa27x_map_io(); |
887 | 891 | ||
888 | iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc)); | 892 | iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc)); |
889 | 893 | ||
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 702f7a68e87d..a4c784aab764 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c | |||
@@ -423,7 +423,7 @@ static void __init zylonite_init(void) | |||
423 | 423 | ||
424 | MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") | 424 | MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") |
425 | .boot_params = 0xa0000100, | 425 | .boot_params = 0xa0000100, |
426 | .map_io = pxa_map_io, | 426 | .map_io = pxa3xx_map_io, |
427 | .nr_irqs = ZYLONITE_NR_IRQS, | 427 | .nr_irqs = ZYLONITE_NR_IRQS, |
428 | .init_irq = pxa3xx_init_irq, | 428 | .init_irq = pxa3xx_init_irq, |
429 | .timer = &pxa_timer, | 429 | .timer = &pxa_timer, |
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index cef6a65637bd..fa2e5bffbb8e 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig | |||
@@ -16,7 +16,7 @@ config CPU_S3C2412 | |||
16 | config CPU_S3C2412_ONLY | 16 | config CPU_S3C2412_ONLY |
17 | bool | 17 | bool |
18 | depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ | 18 | depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ |
19 | !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ | 19 | !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ |
20 | !CPU_S3C2443 && CPU_S3C2412 | 20 | !CPU_S3C2443 && CPU_S3C2412 |
21 | default y if CPU_S3C2412 | 21 | default y if CPU_S3C2412 |
22 | 22 | ||
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 87b9c9f003bd..27b3e7c9d613 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig | |||
@@ -35,9 +35,12 @@ menu "S3C2416 Machines" | |||
35 | config MACH_SMDK2416 | 35 | config MACH_SMDK2416 |
36 | bool "SMDK2416" | 36 | bool "SMDK2416" |
37 | select CPU_S3C2416 | 37 | select CPU_S3C2416 |
38 | select MACH_SMDK | ||
38 | select S3C_DEV_FB | 39 | select S3C_DEV_FB |
39 | select S3C_DEV_HSMMC | 40 | select S3C_DEV_HSMMC |
40 | select S3C_DEV_HSMMC1 | 41 | select S3C_DEV_HSMMC1 |
42 | select S3C_DEV_NAND | ||
43 | select S3C_DEV_USB_HOST | ||
41 | select S3C2416_PM if PM | 44 | select S3C2416_PM if PM |
42 | help | 45 | help |
43 | Say Y here if you are using an SMDK2416 | 46 | Say Y here if you are using an SMDK2416 |
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index ff024a6c0f85..a0cb2581894f 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig | |||
@@ -18,6 +18,7 @@ config CPU_S3C2440 | |||
18 | config CPU_S3C2442 | 18 | config CPU_S3C2442 |
19 | bool | 19 | bool |
20 | select CPU_ARM920T | 20 | select CPU_ARM920T |
21 | select S3C_GPIO_PULL_DOWN | ||
21 | select S3C2410_CLOCK | 22 | select S3C2410_CLOCK |
22 | select S3C2410_GPIO | 23 | select S3C2410_GPIO |
23 | select S3C2410_PM if PM | 24 | select S3C2410_PM if PM |
@@ -178,6 +179,9 @@ config MACH_MINI2440 | |||
178 | bool "MINI2440 development board" | 179 | bool "MINI2440 development board" |
179 | select CPU_S3C2440 | 180 | select CPU_S3C2440 |
180 | select EEPROM_AT24 | 181 | select EEPROM_AT24 |
182 | select NEW_LEDS | ||
183 | select LEDS_CLASS | ||
184 | select LEDS_TRIGGER | ||
181 | select LEDS_TRIGGER_BACKLIGHT | 185 | select LEDS_TRIGGER_BACKLIGHT |
182 | select S3C_DEV_NAND | 186 | select S3C_DEV_NAND |
183 | select S3C_DEV_USB_HOST | 187 | select S3C_DEV_USB_HOST |
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c index d50f3ae6173d..f7663f731ea0 100644 --- a/arch/arm/mach-s3c2440/s3c2440.c +++ b/arch/arm/mach-s3c2440/s3c2440.c | |||
@@ -46,9 +46,6 @@ int __init s3c2440_init(void) | |||
46 | { | 46 | { |
47 | printk("S3C2440: Initialising architecture\n"); | 47 | printk("S3C2440: Initialising architecture\n"); |
48 | 48 | ||
49 | s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; | ||
50 | s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; | ||
51 | |||
52 | /* change irq for watchdog */ | 49 | /* change irq for watchdog */ |
53 | 50 | ||
54 | s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; | 51 | s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; |
@@ -58,3 +55,11 @@ int __init s3c2440_init(void) | |||
58 | 55 | ||
59 | return sysdev_register(&s3c2440_sysdev); | 56 | return sysdev_register(&s3c2440_sysdev); |
60 | } | 57 | } |
58 | |||
59 | void __init s3c2440_map_io(void) | ||
60 | { | ||
61 | s3c244x_map_io(); | ||
62 | |||
63 | s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; | ||
64 | s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; | ||
65 | } | ||
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c index 188ad1e57dc0..ecf813546554 100644 --- a/arch/arm/mach-s3c2440/s3c2442.c +++ b/arch/arm/mach-s3c2440/s3c2442.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/gpio.h> | ||
35 | #include <linux/clk.h> | 36 | #include <linux/clk.h> |
36 | #include <linux/io.h> | 37 | #include <linux/io.h> |
37 | 38 | ||
@@ -43,6 +44,11 @@ | |||
43 | 44 | ||
44 | #include <plat/clock.h> | 45 | #include <plat/clock.h> |
45 | #include <plat/cpu.h> | 46 | #include <plat/cpu.h> |
47 | #include <plat/s3c244x.h> | ||
48 | |||
49 | #include <plat/gpio-core.h> | ||
50 | #include <plat/gpio-cfg.h> | ||
51 | #include <plat/gpio-cfg-helpers.h> | ||
46 | 52 | ||
47 | /* S3C2442 extended clock support */ | 53 | /* S3C2442 extended clock support */ |
48 | 54 | ||
@@ -163,3 +169,11 @@ int __init s3c2442_init(void) | |||
163 | 169 | ||
164 | return sysdev_register(&s3c2442_sysdev); | 170 | return sysdev_register(&s3c2442_sysdev); |
165 | } | 171 | } |
172 | |||
173 | void __init s3c2442_map_io(void) | ||
174 | { | ||
175 | s3c244x_map_io(); | ||
176 | |||
177 | s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down; | ||
178 | s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down; | ||
179 | } | ||
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig index 4fef723126fa..31babec90cec 100644 --- a/arch/arm/mach-s3c2443/Kconfig +++ b/arch/arm/mach-s3c2443/Kconfig | |||
@@ -5,6 +5,7 @@ | |||
5 | config CPU_S3C2443 | 5 | config CPU_S3C2443 |
6 | bool | 6 | bool |
7 | depends on ARCH_S3C2410 | 7 | depends on ARCH_S3C2410 |
8 | select CPU_ARM920T | ||
8 | select S3C2443_DMA if S3C2410_DMA | 9 | select S3C2443_DMA if S3C2410_DMA |
9 | select CPU_LLSERIAL_S3C2440 | 10 | select CPU_LLSERIAL_S3C2440 |
10 | select SAMSUNG_CLKSRC | 11 | select SAMSUNG_CLKSRC |
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 9e27a84433cb..12052e8e064c 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -2,14 +2,16 @@ | |||
2 | # Makefile for the linux kernel, U8500 machine. | 2 | # Makefile for the linux kernel, U8500 machine. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := clock.o cpu.o devices.o | 5 | obj-y := clock.o cpu.o devices.o devices-common.o |
6 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o | 6 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o |
7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o | 7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o |
8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o | 8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o \ |
9 | obj-$(CONFIG_MACH_U5500) += board-u5500.o | 9 | board-mop500-keypads.o |
10 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o | ||
10 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
11 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 12 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
12 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | 13 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o |
13 | obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o | 14 | obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o |
14 | obj-$(CONFIG_U5500_MODEM_IRQ) += modem_irq.o | 15 | obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o |
15 | obj-$(CONFIG_U5500_MBOX) += mbox.o | 16 | obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o |
17 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | ||
diff --git a/arch/arm/mach-ux500/board-mop500-keypads.c b/arch/arm/mach-ux500/board-mop500-keypads.c new file mode 100644 index 000000000000..70318c354d32 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-keypads.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * | ||
6 | * Keypad layouts for various boards | ||
7 | */ | ||
8 | |||
9 | #include <linux/i2c.h> | ||
10 | #include <linux/gpio.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mfd/stmpe.h> | ||
14 | #include <linux/mfd/tc3589x.h> | ||
15 | #include <linux/input/matrix_keypad.h> | ||
16 | |||
17 | #include <plat/pincfg.h> | ||
18 | #include <plat/ske.h> | ||
19 | |||
20 | #include <mach/devices.h> | ||
21 | #include <mach/hardware.h> | ||
22 | |||
23 | #include "devices-db8500.h" | ||
24 | #include "board-mop500.h" | ||
25 | |||
26 | /* STMPE/SKE keypad use this key layout */ | ||
27 | static const unsigned int mop500_keymap[] = { | ||
28 | KEY(2, 5, KEY_END), | ||
29 | KEY(4, 1, KEY_POWER), | ||
30 | KEY(3, 5, KEY_VOLUMEDOWN), | ||
31 | KEY(1, 3, KEY_3), | ||
32 | KEY(5, 2, KEY_RIGHT), | ||
33 | KEY(5, 0, KEY_9), | ||
34 | |||
35 | KEY(0, 5, KEY_MENU), | ||
36 | KEY(7, 6, KEY_ENTER), | ||
37 | KEY(4, 5, KEY_0), | ||
38 | KEY(6, 7, KEY_2), | ||
39 | KEY(3, 4, KEY_UP), | ||
40 | KEY(3, 3, KEY_DOWN), | ||
41 | |||
42 | KEY(6, 4, KEY_SEND), | ||
43 | KEY(6, 2, KEY_BACK), | ||
44 | KEY(4, 2, KEY_VOLUMEUP), | ||
45 | KEY(5, 5, KEY_1), | ||
46 | KEY(4, 3, KEY_LEFT), | ||
47 | KEY(3, 2, KEY_7), | ||
48 | }; | ||
49 | |||
50 | static const struct matrix_keymap_data mop500_keymap_data = { | ||
51 | .keymap = mop500_keymap, | ||
52 | .keymap_size = ARRAY_SIZE(mop500_keymap), | ||
53 | }; | ||
54 | |||
55 | /* | ||
56 | * Nomadik SKE keypad | ||
57 | */ | ||
58 | #define ROW_PIN_I0 164 | ||
59 | #define ROW_PIN_I1 163 | ||
60 | #define ROW_PIN_I2 162 | ||
61 | #define ROW_PIN_I3 161 | ||
62 | #define ROW_PIN_I4 156 | ||
63 | #define ROW_PIN_I5 155 | ||
64 | #define ROW_PIN_I6 154 | ||
65 | #define ROW_PIN_I7 153 | ||
66 | #define COL_PIN_O0 168 | ||
67 | #define COL_PIN_O1 167 | ||
68 | #define COL_PIN_O2 166 | ||
69 | #define COL_PIN_O3 165 | ||
70 | #define COL_PIN_O4 160 | ||
71 | #define COL_PIN_O5 159 | ||
72 | #define COL_PIN_O6 158 | ||
73 | #define COL_PIN_O7 157 | ||
74 | |||
75 | #define SKE_KPD_MAX_ROWS 8 | ||
76 | #define SKE_KPD_MAX_COLS 8 | ||
77 | |||
78 | static int ske_kp_rows[] = { | ||
79 | ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3, | ||
80 | ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7, | ||
81 | }; | ||
82 | |||
83 | /* | ||
84 | * ske_set_gpio_row: request and set gpio rows | ||
85 | */ | ||
86 | static int ske_set_gpio_row(int gpio) | ||
87 | { | ||
88 | int ret; | ||
89 | |||
90 | ret = gpio_request(gpio, "ske-kp"); | ||
91 | if (ret < 0) { | ||
92 | pr_err("ske_set_gpio_row: gpio request failed\n"); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | ret = gpio_direction_output(gpio, 1); | ||
97 | if (ret < 0) { | ||
98 | pr_err("ske_set_gpio_row: gpio direction failed\n"); | ||
99 | gpio_free(gpio); | ||
100 | } | ||
101 | |||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * ske_kp_init - enable the gpio configuration | ||
107 | */ | ||
108 | static int ske_kp_init(void) | ||
109 | { | ||
110 | int ret, i; | ||
111 | |||
112 | for (i = 0; i < SKE_KPD_MAX_ROWS; i++) { | ||
113 | ret = ske_set_gpio_row(ske_kp_rows[i]); | ||
114 | if (ret < 0) { | ||
115 | pr_err("ske_kp_init: failed init\n"); | ||
116 | return ret; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static struct ske_keypad_platform_data ske_keypad_board = { | ||
124 | .init = ske_kp_init, | ||
125 | .keymap_data = &mop500_keymap_data, | ||
126 | .no_autorepeat = true, | ||
127 | .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */ | ||
128 | .kcol = SKE_KPD_MAX_COLS, | ||
129 | .debounce_ms = 40, /* in millisecs */ | ||
130 | }; | ||
131 | |||
132 | /* | ||
133 | * STMPE1601 | ||
134 | */ | ||
135 | static struct stmpe_keypad_platform_data stmpe1601_keypad_data = { | ||
136 | .debounce_ms = 64, | ||
137 | .scan_count = 8, | ||
138 | .no_autorepeat = true, | ||
139 | .keymap_data = &mop500_keymap_data, | ||
140 | }; | ||
141 | |||
142 | static struct stmpe_platform_data stmpe1601_data = { | ||
143 | .id = 1, | ||
144 | .blocks = STMPE_BLOCK_KEYPAD, | ||
145 | .irq_trigger = IRQF_TRIGGER_FALLING, | ||
146 | .irq_base = MOP500_STMPE1601_IRQ(0), | ||
147 | .keypad = &stmpe1601_keypad_data, | ||
148 | .autosleep = true, | ||
149 | .autosleep_timeout = 1024, | ||
150 | }; | ||
151 | |||
152 | static struct i2c_board_info mop500_i2c0_devices_stuib[] = { | ||
153 | { | ||
154 | I2C_BOARD_INFO("stmpe1601", 0x40), | ||
155 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
156 | .platform_data = &stmpe1601_data, | ||
157 | .flags = I2C_CLIENT_WAKE, | ||
158 | }, | ||
159 | }; | ||
160 | |||
161 | /* | ||
162 | * TC35893 | ||
163 | */ | ||
164 | |||
165 | static const unsigned int uib_keymap[] = { | ||
166 | KEY(3, 1, KEY_END), | ||
167 | KEY(4, 1, KEY_POWER), | ||
168 | KEY(6, 4, KEY_VOLUMEDOWN), | ||
169 | KEY(4, 2, KEY_EMAIL), | ||
170 | KEY(3, 3, KEY_RIGHT), | ||
171 | KEY(2, 5, KEY_BACKSPACE), | ||
172 | |||
173 | KEY(6, 7, KEY_MENU), | ||
174 | KEY(5, 0, KEY_ENTER), | ||
175 | KEY(4, 3, KEY_0), | ||
176 | KEY(3, 4, KEY_DOT), | ||
177 | KEY(5, 2, KEY_UP), | ||
178 | KEY(3, 5, KEY_DOWN), | ||
179 | |||
180 | KEY(4, 5, KEY_SEND), | ||
181 | KEY(0, 5, KEY_BACK), | ||
182 | KEY(6, 2, KEY_VOLUMEUP), | ||
183 | KEY(1, 3, KEY_SPACE), | ||
184 | KEY(7, 6, KEY_LEFT), | ||
185 | KEY(5, 5, KEY_SEARCH), | ||
186 | }; | ||
187 | |||
188 | static struct matrix_keymap_data uib_keymap_data = { | ||
189 | .keymap = uib_keymap, | ||
190 | .keymap_size = ARRAY_SIZE(uib_keymap), | ||
191 | }; | ||
192 | |||
193 | static struct tc3589x_keypad_platform_data tc35893_data = { | ||
194 | .krow = TC_KPD_ROWS, | ||
195 | .kcol = TC_KPD_COLUMNS, | ||
196 | .debounce_period = TC_KPD_DEBOUNCE_PERIOD, | ||
197 | .settle_time = TC_KPD_SETTLE_TIME, | ||
198 | .irqtype = IRQF_TRIGGER_FALLING, | ||
199 | .enable_wakeup = true, | ||
200 | .keymap_data = &uib_keymap_data, | ||
201 | .no_autorepeat = true, | ||
202 | }; | ||
203 | |||
204 | static struct tc3589x_platform_data tc3589x_keypad_data = { | ||
205 | .block = TC3589x_BLOCK_KEYPAD, | ||
206 | .keypad = &tc35893_data, | ||
207 | .irq_base = MOP500_EGPIO_IRQ_BASE, | ||
208 | }; | ||
209 | |||
210 | static struct i2c_board_info mop500_i2c0_devices_uib[] = { | ||
211 | { | ||
212 | I2C_BOARD_INFO("tc3589x", 0x44), | ||
213 | .platform_data = &tc3589x_keypad_data, | ||
214 | .irq = NOMADIK_GPIO_TO_IRQ(218), | ||
215 | .flags = I2C_CLIENT_WAKE, | ||
216 | }, | ||
217 | }; | ||
218 | |||
219 | void mop500_keypad_init(void) | ||
220 | { | ||
221 | db8500_add_ske_keypad(&ske_keypad_board); | ||
222 | |||
223 | i2c_register_board_info(0, mop500_i2c0_devices_stuib, | ||
224 | ARRAY_SIZE(mop500_i2c0_devices_stuib)); | ||
225 | |||
226 | i2c_register_board_info(0, mop500_i2c0_devices_uib, | ||
227 | ARRAY_SIZE(mop500_i2c0_devices_uib)); | ||
228 | |||
229 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index bac995665b58..4b996676594e 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
@@ -16,10 +16,24 @@ | |||
16 | #include <mach/devices.h> | 16 | #include <mach/devices.h> |
17 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
18 | 18 | ||
19 | #include "devices-db8500.h" | ||
19 | #include "pins-db8500.h" | 20 | #include "pins-db8500.h" |
20 | #include "board-mop500.h" | 21 | #include "board-mop500.h" |
21 | 22 | ||
22 | static pin_cfg_t mop500_sdi_pins[] = { | 23 | static pin_cfg_t mop500_sdi_pins[] = { |
24 | /* SDI0 (MicroSD slot) */ | ||
25 | GPIO18_MC0_CMDDIR, | ||
26 | GPIO19_MC0_DAT0DIR, | ||
27 | GPIO20_MC0_DAT2DIR, | ||
28 | GPIO21_MC0_DAT31DIR, | ||
29 | GPIO22_MC0_FBCLK, | ||
30 | GPIO23_MC0_CLK, | ||
31 | GPIO24_MC0_CMD, | ||
32 | GPIO25_MC0_DAT0, | ||
33 | GPIO26_MC0_DAT1, | ||
34 | GPIO27_MC0_DAT2, | ||
35 | GPIO28_MC0_DAT3, | ||
36 | |||
23 | /* SDI4 (on-board eMMC) */ | 37 | /* SDI4 (on-board eMMC) */ |
24 | GPIO197_MC4_DAT3, | 38 | GPIO197_MC4_DAT3, |
25 | GPIO198_MC4_DAT2, | 39 | GPIO198_MC4_DAT2, |
@@ -50,6 +64,55 @@ static pin_cfg_t mop500_sdi2_pins[] = { | |||
50 | }; | 64 | }; |
51 | 65 | ||
52 | /* | 66 | /* |
67 | * SDI 0 (MicroSD slot) | ||
68 | */ | ||
69 | |||
70 | /* MMCIPOWER bits */ | ||
71 | #define MCI_DATA2DIREN (1 << 2) | ||
72 | #define MCI_CMDDIREN (1 << 3) | ||
73 | #define MCI_DATA0DIREN (1 << 4) | ||
74 | #define MCI_DATA31DIREN (1 << 5) | ||
75 | #define MCI_FBCLKEN (1 << 7) | ||
76 | |||
77 | static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, | ||
78 | unsigned char power_mode) | ||
79 | { | ||
80 | if (power_mode == MMC_POWER_UP) | ||
81 | gpio_set_value_cansleep(GPIO_SDMMC_EN, 1); | ||
82 | else if (power_mode == MMC_POWER_OFF) | ||
83 | gpio_set_value_cansleep(GPIO_SDMMC_EN, 0); | ||
84 | |||
85 | return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | | ||
86 | MCI_DATA2DIREN | MCI_DATA31DIREN; | ||
87 | } | ||
88 | |||
89 | static struct mmci_platform_data mop500_sdi0_data = { | ||
90 | .vdd_handler = mop500_sdi0_vdd_handler, | ||
91 | .ocr_mask = MMC_VDD_29_30, | ||
92 | .f_max = 100000000, | ||
93 | .capabilities = MMC_CAP_4_BIT_DATA, | ||
94 | .gpio_cd = GPIO_SDMMC_CD, | ||
95 | .gpio_wp = -1, | ||
96 | }; | ||
97 | |||
98 | void mop500_sdi_tc35892_init(void) | ||
99 | { | ||
100 | int ret; | ||
101 | |||
102 | ret = gpio_request(GPIO_SDMMC_EN, "SDMMC_EN"); | ||
103 | if (!ret) | ||
104 | ret = gpio_request(GPIO_SDMMC_1V8_3V_SEL, | ||
105 | "GPIO_SDMMC_1V8_3V_SEL"); | ||
106 | if (ret) | ||
107 | return; | ||
108 | |||
109 | gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1); | ||
110 | gpio_direction_output(GPIO_SDMMC_EN, 0); | ||
111 | |||
112 | db8500_add_sdi0(&mop500_sdi0_data); | ||
113 | } | ||
114 | |||
115 | /* | ||
53 | * SDI 2 (POP eMMC, not on DB8500ed) | 116 | * SDI 2 (POP eMMC, not on DB8500ed) |
54 | */ | 117 | */ |
55 | 118 | ||
@@ -74,18 +137,24 @@ static struct mmci_platform_data mop500_sdi4_data = { | |||
74 | .gpio_wp = -1, | 137 | .gpio_wp = -1, |
75 | }; | 138 | }; |
76 | 139 | ||
77 | void mop500_sdi_init(void) | 140 | void __init mop500_sdi_init(void) |
78 | { | 141 | { |
79 | nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins)); | 142 | nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins)); |
80 | 143 | ||
81 | u8500_sdi2_device.dev.platform_data = &mop500_sdi2_data; | 144 | /* |
82 | u8500_sdi4_device.dev.platform_data = &mop500_sdi4_data; | 145 | * sdi0 will finally be added when the TC35892 initializes and calls |
146 | * mop500_sdi_tc35892_init() above. | ||
147 | */ | ||
83 | 148 | ||
149 | /* PoP:ed eMMC */ | ||
84 | if (!cpu_is_u8500ed()) { | 150 | if (!cpu_is_u8500ed()) { |
85 | nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins)); | 151 | nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins)); |
86 | amba_device_register(&u8500_sdi2_device, &iomem_resource); | 152 | /* POP eMMC on v1.0 has problems with high speed */ |
153 | if (!cpu_is_u8500v10()) | ||
154 | mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; | ||
155 | db8500_add_sdi2(&mop500_sdi2_data); | ||
87 | } | 156 | } |
88 | 157 | ||
89 | /* On-board eMMC */ | 158 | /* On-board eMMC */ |
90 | amba_device_register(&u8500_sdi4_device, &iomem_resource); | 159 | db8500_add_sdi4(&mop500_sdi4_data); |
91 | } | 160 | } |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index cac83a694880..a1c9ea1a66df 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -13,25 +13,26 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/i2c.h> | ||
16 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
17 | #include <linux/amba/bus.h> | 18 | #include <linux/amba/bus.h> |
18 | #include <linux/amba/pl022.h> | 19 | #include <linux/amba/pl022.h> |
19 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
20 | #include <linux/mfd/ab8500.h> | 21 | #include <linux/mfd/ab8500.h> |
21 | #include <linux/input/matrix_keypad.h> | 22 | #include <linux/mfd/tc3589x.h> |
22 | 23 | ||
23 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
24 | #include <asm/mach/arch.h> | 25 | #include <asm/mach/arch.h> |
25 | 26 | ||
26 | #include <plat/pincfg.h> | 27 | #include <plat/pincfg.h> |
27 | #include <plat/i2c.h> | 28 | #include <plat/i2c.h> |
28 | #include <plat/ske.h> | ||
29 | 29 | ||
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
31 | #include <mach/setup.h> | 31 | #include <mach/setup.h> |
32 | #include <mach/devices.h> | 32 | #include <mach/devices.h> |
33 | #include <mach/irqs.h> | 33 | #include <mach/irqs.h> |
34 | 34 | ||
35 | #include "devices-db8500.h" | ||
35 | #include "pins-db8500.h" | 36 | #include "pins-db8500.h" |
36 | #include "board-mop500.h" | 37 | #include "board-mop500.h" |
37 | 38 | ||
@@ -69,22 +70,12 @@ static pin_cfg_t mop500_pins[] = { | |||
69 | GPIO166_KP_O2, | 70 | GPIO166_KP_O2, |
70 | GPIO167_KP_O1, | 71 | GPIO167_KP_O1, |
71 | GPIO168_KP_O0, | 72 | GPIO168_KP_O0, |
72 | }; | ||
73 | 73 | ||
74 | static void ab4500_spi_cs_control(u32 command) | 74 | /* GPIO_EXP_INT */ |
75 | { | 75 | GPIO217_GPIO, |
76 | /* set the FRM signal, which is CS - TODO */ | ||
77 | } | ||
78 | 76 | ||
79 | struct pl022_config_chip ab4500_chip_info = { | 77 | /* STMPE1601 IRQ */ |
80 | .com_mode = INTERRUPT_TRANSFER, | 78 | GPIO218_GPIO | PIN_INPUT_PULLUP, |
81 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | ||
82 | /* we can act as master only */ | ||
83 | .hierarchy = SSP_MASTER, | ||
84 | .slave_tx_disable = 0, | ||
85 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, | ||
86 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, | ||
87 | .cs_control = ab4500_spi_cs_control, | ||
88 | }; | 79 | }; |
89 | 80 | ||
90 | static struct ab8500_platform_data ab8500_platdata = { | 81 | static struct ab8500_platform_data ab8500_platdata = { |
@@ -93,9 +84,9 @@ static struct ab8500_platform_data ab8500_platdata = { | |||
93 | 84 | ||
94 | static struct resource ab8500_resources[] = { | 85 | static struct resource ab8500_resources[] = { |
95 | [0] = { | 86 | [0] = { |
96 | .start = IRQ_AB8500, | 87 | .start = IRQ_DB8500_AB8500, |
97 | .end = IRQ_AB8500, | 88 | .end = IRQ_DB8500_AB8500, |
98 | .flags = IORESOURCE_IRQ | 89 | .flags = IORESOURCE_IRQ |
99 | } | 90 | } |
100 | }; | 91 | }; |
101 | 92 | ||
@@ -109,19 +100,6 @@ struct platform_device ab8500_device = { | |||
109 | .resource = ab8500_resources, | 100 | .resource = ab8500_resources, |
110 | }; | 101 | }; |
111 | 102 | ||
112 | static struct spi_board_info ab8500_spi_devices[] = { | ||
113 | { | ||
114 | .modalias = "ab8500-spi", | ||
115 | .controller_data = &ab4500_chip_info, | ||
116 | .platform_data = &ab8500_platdata, | ||
117 | .max_speed_hz = 12000000, | ||
118 | .bus_num = 0, | ||
119 | .chip_select = 0, | ||
120 | .mode = SPI_MODE_3, | ||
121 | .irq = IRQ_DB8500_AB8500, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | static struct pl022_ssp_controller ssp0_platform_data = { | 103 | static struct pl022_ssp_controller ssp0_platform_data = { |
126 | .bus_id = 0, | 104 | .bus_id = 0, |
127 | /* pl022 not yet supports dma */ | 105 | /* pl022 not yet supports dma */ |
@@ -132,6 +110,34 @@ static struct pl022_ssp_controller ssp0_platform_data = { | |||
132 | .num_chipselect = 5, | 110 | .num_chipselect = 5, |
133 | }; | 111 | }; |
134 | 112 | ||
113 | /* | ||
114 | * TC35892 | ||
115 | */ | ||
116 | |||
117 | static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base) | ||
118 | { | ||
119 | mop500_sdi_tc35892_init(); | ||
120 | } | ||
121 | |||
122 | static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = { | ||
123 | .gpio_base = MOP500_EGPIO(0), | ||
124 | .setup = mop500_tc35892_init, | ||
125 | }; | ||
126 | |||
127 | static struct tc3589x_platform_data mop500_tc35892_data = { | ||
128 | .block = TC3589x_BLOCK_GPIO, | ||
129 | .gpio = &mop500_tc35892_gpio_data, | ||
130 | .irq_base = MOP500_EGPIO_IRQ_BASE, | ||
131 | }; | ||
132 | |||
133 | static struct i2c_board_info mop500_i2c0_devices[] = { | ||
134 | { | ||
135 | I2C_BOARD_INFO("tc3589x", 0x42), | ||
136 | .irq = NOMADIK_GPIO_TO_IRQ(217), | ||
137 | .platform_data = &mop500_tc35892_data, | ||
138 | }, | ||
139 | }; | ||
140 | |||
135 | #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ | 141 | #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ |
136 | static struct nmk_i2c_controller u8500_i2c##id##_data = { \ | 142 | static struct nmk_i2c_controller u8500_i2c##id##_data = { \ |
137 | /* \ | 143 | /* \ |
@@ -161,159 +167,49 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | |||
161 | U8500_I2C_CONTROLLER(2, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 167 | U8500_I2C_CONTROLLER(2, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); |
162 | U8500_I2C_CONTROLLER(3, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); | 168 | U8500_I2C_CONTROLLER(3, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD); |
163 | 169 | ||
164 | static struct amba_device *amba_devs[] __initdata = { | 170 | static void __init mop500_i2c_init(void) |
165 | &ux500_uart0_device, | 171 | { |
166 | &ux500_uart1_device, | 172 | db8500_add_i2c0(&u8500_i2c0_data); |
167 | &ux500_uart2_device, | 173 | db8500_add_i2c1(&u8500_i2c1_data); |
168 | &u8500_ssp0_device, | 174 | db8500_add_i2c2(&u8500_i2c2_data); |
169 | }; | 175 | db8500_add_i2c3(&u8500_i2c3_data); |
170 | 176 | } | |
171 | static const unsigned int ux500_keymap[] = { | ||
172 | KEY(2, 5, KEY_END), | ||
173 | KEY(4, 1, KEY_POWER), | ||
174 | KEY(3, 5, KEY_VOLUMEDOWN), | ||
175 | KEY(1, 3, KEY_3), | ||
176 | KEY(5, 2, KEY_RIGHT), | ||
177 | KEY(5, 0, KEY_9), | ||
178 | |||
179 | KEY(0, 5, KEY_MENU), | ||
180 | KEY(7, 6, KEY_ENTER), | ||
181 | KEY(4, 5, KEY_0), | ||
182 | KEY(6, 7, KEY_2), | ||
183 | KEY(3, 4, KEY_UP), | ||
184 | KEY(3, 3, KEY_DOWN), | ||
185 | |||
186 | KEY(6, 4, KEY_SEND), | ||
187 | KEY(6, 2, KEY_BACK), | ||
188 | KEY(4, 2, KEY_VOLUMEUP), | ||
189 | KEY(5, 5, KEY_1), | ||
190 | KEY(4, 3, KEY_LEFT), | ||
191 | KEY(3, 2, KEY_7), | ||
192 | }; | ||
193 | |||
194 | static const struct matrix_keymap_data ux500_keymap_data = { | ||
195 | .keymap = ux500_keymap, | ||
196 | .keymap_size = ARRAY_SIZE(ux500_keymap), | ||
197 | }; | ||
198 | 177 | ||
199 | /* | 178 | /* add any platform devices here - TODO */ |
200 | * Nomadik SKE keypad | 179 | static struct platform_device *platform_devs[] __initdata = { |
201 | */ | ||
202 | #define ROW_PIN_I0 164 | ||
203 | #define ROW_PIN_I1 163 | ||
204 | #define ROW_PIN_I2 162 | ||
205 | #define ROW_PIN_I3 161 | ||
206 | #define ROW_PIN_I4 156 | ||
207 | #define ROW_PIN_I5 155 | ||
208 | #define ROW_PIN_I6 154 | ||
209 | #define ROW_PIN_I7 153 | ||
210 | #define COL_PIN_O0 168 | ||
211 | #define COL_PIN_O1 167 | ||
212 | #define COL_PIN_O2 166 | ||
213 | #define COL_PIN_O3 165 | ||
214 | #define COL_PIN_O4 160 | ||
215 | #define COL_PIN_O5 159 | ||
216 | #define COL_PIN_O6 158 | ||
217 | #define COL_PIN_O7 157 | ||
218 | |||
219 | #define SKE_KPD_MAX_ROWS 8 | ||
220 | #define SKE_KPD_MAX_COLS 8 | ||
221 | |||
222 | static int ske_kp_rows[] = { | ||
223 | ROW_PIN_I0, ROW_PIN_I1, ROW_PIN_I2, ROW_PIN_I3, | ||
224 | ROW_PIN_I4, ROW_PIN_I5, ROW_PIN_I6, ROW_PIN_I7, | ||
225 | }; | 180 | }; |
226 | 181 | ||
227 | /* | 182 | static void __init mop500_spi_init(void) |
228 | * ske_set_gpio_row: request and set gpio rows | ||
229 | */ | ||
230 | static int ske_set_gpio_row(int gpio) | ||
231 | { | 183 | { |
232 | int ret; | 184 | db8500_add_ssp0(&ssp0_platform_data); |
233 | |||
234 | ret = gpio_request(gpio, "ske-kp"); | ||
235 | if (ret < 0) { | ||
236 | pr_err("ske_set_gpio_row: gpio request failed\n"); | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | ret = gpio_direction_output(gpio, 1); | ||
241 | if (ret < 0) { | ||
242 | pr_err("ske_set_gpio_row: gpio direction failed\n"); | ||
243 | gpio_free(gpio); | ||
244 | } | ||
245 | |||
246 | return ret; | ||
247 | } | 185 | } |
248 | 186 | ||
249 | /* | 187 | static void __init mop500_uart_init(void) |
250 | * ske_kp_init - enable the gpio configuration | ||
251 | */ | ||
252 | static int ske_kp_init(void) | ||
253 | { | 188 | { |
254 | int ret, i; | 189 | db8500_add_uart0(); |
255 | 190 | db8500_add_uart1(); | |
256 | for (i = 0; i < SKE_KPD_MAX_ROWS; i++) { | 191 | db8500_add_uart2(); |
257 | ret = ske_set_gpio_row(ske_kp_rows[i]); | ||
258 | if (ret < 0) { | ||
259 | pr_err("ske_kp_init: failed init\n"); | ||
260 | return ret; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | return 0; | ||
265 | } | 192 | } |
266 | 193 | ||
267 | static struct ske_keypad_platform_data ske_keypad_board = { | ||
268 | .init = ske_kp_init, | ||
269 | .keymap_data = &ux500_keymap_data, | ||
270 | .no_autorepeat = true, | ||
271 | .krow = SKE_KPD_MAX_ROWS, /* 8x8 matrix */ | ||
272 | .kcol = SKE_KPD_MAX_COLS, | ||
273 | .debounce_ms = 40, /* in millsecs */ | ||
274 | }; | ||
275 | |||
276 | |||
277 | |||
278 | /* add any platform devices here - TODO */ | ||
279 | static struct platform_device *platform_devs[] __initdata = { | ||
280 | &u8500_i2c0_device, | ||
281 | &ux500_i2c1_device, | ||
282 | &ux500_i2c2_device, | ||
283 | &ux500_i2c3_device, | ||
284 | &ux500_ske_keypad_device, | ||
285 | }; | ||
286 | |||
287 | static void __init u8500_init_machine(void) | 194 | static void __init u8500_init_machine(void) |
288 | { | 195 | { |
289 | int i; | ||
290 | |||
291 | u8500_init_devices(); | 196 | u8500_init_devices(); |
292 | 197 | ||
293 | nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins)); | 198 | nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins)); |
294 | 199 | ||
295 | u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data; | ||
296 | ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data; | ||
297 | ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data; | ||
298 | ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data; | ||
299 | ux500_ske_keypad_device.dev.platform_data = &ske_keypad_board; | ||
300 | |||
301 | u8500_ssp0_device.dev.platform_data = &ssp0_platform_data; | ||
302 | |||
303 | /* Register the active AMBA devices on this board */ | ||
304 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) | ||
305 | amba_device_register(amba_devs[i], &iomem_resource); | ||
306 | |||
307 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 200 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
308 | 201 | ||
202 | mop500_i2c_init(); | ||
309 | mop500_sdi_init(); | 203 | mop500_sdi_init(); |
204 | mop500_spi_init(); | ||
205 | mop500_uart_init(); | ||
206 | |||
207 | mop500_keypad_init(); | ||
208 | |||
209 | platform_device_register(&ab8500_device); | ||
310 | 210 | ||
311 | /* If HW is early drop (ED) or V1.0 then use SPI to access AB8500 */ | 211 | i2c_register_board_info(0, mop500_i2c0_devices, |
312 | if (cpu_is_u8500ed() || cpu_is_u8500v10()) | 212 | ARRAY_SIZE(mop500_i2c0_devices)); |
313 | spi_register_board_info(ab8500_spi_devices, | ||
314 | ARRAY_SIZE(ab8500_spi_devices)); | ||
315 | else /* If HW is v.1.1 or later use I2C to access AB8500 */ | ||
316 | platform_device_register(&ab8500_device); | ||
317 | } | 213 | } |
318 | 214 | ||
319 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | 215 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") |
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 2d240322fa6f..3104ae2a02c2 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h | |||
@@ -7,6 +7,15 @@ | |||
7 | #ifndef __BOARD_MOP500_H | 7 | #ifndef __BOARD_MOP500_H |
8 | #define __BOARD_MOP500_H | 8 | #define __BOARD_MOP500_H |
9 | 9 | ||
10 | #define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) | ||
11 | |||
12 | /* GPIOs on the TC35892 expander */ | ||
13 | #define GPIO_SDMMC_CD MOP500_EGPIO(3) | ||
14 | #define GPIO_SDMMC_EN MOP500_EGPIO(17) | ||
15 | #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) | ||
16 | |||
10 | extern void mop500_sdi_init(void); | 17 | extern void mop500_sdi_init(void); |
18 | extern void mop500_sdi_tc35892_init(void); | ||
19 | extern void mop500_keypad_init(void); | ||
11 | 20 | ||
12 | #endif | 21 | #endif |
diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c new file mode 100644 index 000000000000..54712acc0394 --- /dev/null +++ b/arch/arm/mach-ux500/board-u5500-sdi.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Hanumath Prasad <ulf.hansson@stericsson.com> | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/amba/mmci.h> | ||
9 | #include <linux/mmc/host.h> | ||
10 | #include <linux/gpio.h> | ||
11 | |||
12 | #include <plat/pincfg.h> | ||
13 | #include <mach/db5500-regs.h> | ||
14 | #include <plat/ste_dma40.h> | ||
15 | |||
16 | #include "pins-db5500.h" | ||
17 | #include "devices-db5500.h" | ||
18 | #include "ste-dma40-db5500.h" | ||
19 | |||
20 | static pin_cfg_t u5500_sdi_pins[] = { | ||
21 | /* SDI0 (POP eMMC) */ | ||
22 | GPIO5_MC0_DAT0 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
23 | GPIO6_MC0_DAT1 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
24 | GPIO7_MC0_DAT2 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
25 | GPIO8_MC0_DAT3 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
26 | GPIO9_MC0_DAT4 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
27 | GPIO10_MC0_DAT5 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
28 | GPIO11_MC0_DAT6 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
29 | GPIO12_MC0_DAT7 | PIN_DIR_INPUT | PIN_PULL_UP, | ||
30 | GPIO13_MC0_CMD | PIN_DIR_INPUT | PIN_PULL_UP, | ||
31 | GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW, | ||
32 | }; | ||
33 | |||
34 | static struct mmci_platform_data u5500_sdi0_data = { | ||
35 | .ocr_mask = MMC_VDD_165_195, | ||
36 | .f_max = 50000000, | ||
37 | .capabilities = MMC_CAP_4_BIT_DATA | | ||
38 | MMC_CAP_8_BIT_DATA | | ||
39 | MMC_CAP_MMC_HIGHSPEED, | ||
40 | .gpio_cd = -1, | ||
41 | .gpio_wp = -1, | ||
42 | }; | ||
43 | |||
44 | void __init u5500_sdi_init(void) | ||
45 | { | ||
46 | nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins)); | ||
47 | |||
48 | db5500_add_sdi0(&u5500_sdi0_data); | ||
49 | } | ||
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 1ca094a45e71..39d370c1f3b4 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
10 | #include <linux/amba/bus.h> | 10 | #include <linux/amba/bus.h> |
11 | #include <linux/gpio.h> | 11 | #include <linux/gpio.h> |
12 | #include <linux/irq.h> | ||
12 | 13 | ||
13 | #include <asm/mach/arch.h> | 14 | #include <asm/mach/arch.h> |
14 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
@@ -17,20 +18,24 @@ | |||
17 | #include <mach/devices.h> | 18 | #include <mach/devices.h> |
18 | #include <mach/setup.h> | 19 | #include <mach/setup.h> |
19 | 20 | ||
20 | static struct amba_device *amba_board_devs[] __initdata = { | 21 | #include "devices-db5500.h" |
21 | &ux500_uart0_device, | 22 | |
22 | &ux500_uart1_device, | 23 | static void __init u5500_uart_init(void) |
23 | &ux500_uart2_device, | 24 | { |
24 | }; | 25 | db5500_add_uart0(); |
26 | db5500_add_uart1(); | ||
27 | db5500_add_uart2(); | ||
28 | } | ||
25 | 29 | ||
26 | static void __init u5500_init_machine(void) | 30 | static void __init u5500_init_machine(void) |
27 | { | 31 | { |
28 | u5500_init_devices(); | 32 | u5500_init_devices(); |
29 | 33 | ||
30 | amba_add_devices(amba_board_devs, ARRAY_SIZE(amba_board_devs)); | 34 | u5500_sdi_init(); |
35 | u5500_uart_init(); | ||
31 | } | 36 | } |
32 | 37 | ||
33 | MACHINE_START(U8500, "ST-Ericsson U5500 Platform") | 38 | MACHINE_START(U5500, "ST-Ericsson U5500 Platform") |
34 | .boot_params = 0x00000100, | 39 | .boot_params = 0x00000100, |
35 | .map_io = u5500_map_io, | 40 | .map_io = u5500_map_io, |
36 | .init_irq = ux500_init_irq, | 41 | .init_irq = ux500_init_irq, |
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 1675047daf20..912d1cc18c57 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c | |||
@@ -20,6 +20,12 @@ | |||
20 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
21 | #include "clock.h" | 21 | #include "clock.h" |
22 | 22 | ||
23 | #ifdef CONFIG_DEBUG_FS | ||
24 | #include <linux/debugfs.h> | ||
25 | #include <linux/uaccess.h> /* for copy_from_user */ | ||
26 | static LIST_HEAD(clk_list); | ||
27 | #endif | ||
28 | |||
23 | #define PRCC_PCKEN 0x00 | 29 | #define PRCC_PCKEN 0x00 |
24 | #define PRCC_PCKDIS 0x04 | 30 | #define PRCC_PCKDIS 0x04 |
25 | #define PRCC_KCKEN 0x08 | 31 | #define PRCC_KCKEN 0x08 |
@@ -133,7 +139,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
133 | { | 139 | { |
134 | void __iomem *addr = __io_address(UX500_PRCMU_BASE) | 140 | void __iomem *addr = __io_address(UX500_PRCMU_BASE) |
135 | + PRCM_TCR; | 141 | + PRCM_TCR; |
136 | u32 tcr = readl(addr); | 142 | u32 tcr; |
137 | int mtu = (int) clk->data; | 143 | int mtu = (int) clk->data; |
138 | /* | 144 | /* |
139 | * One of these is selected eventually | 145 | * One of these is selected eventually |
@@ -144,6 +150,14 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
144 | unsigned long mturate; | 150 | unsigned long mturate; |
145 | unsigned long retclk; | 151 | unsigned long retclk; |
146 | 152 | ||
153 | /* | ||
154 | * On a startup, always conifgure the TCR to the doze mode; | ||
155 | * bootloaders do it for us. Do this in the kernel too. | ||
156 | */ | ||
157 | writel(PRCM_TCR_DOZE_MODE, addr); | ||
158 | |||
159 | tcr = readl(addr); | ||
160 | |||
147 | /* Get the rate from the parent as a default */ | 161 | /* Get the rate from the parent as a default */ |
148 | if (clk->parent_periph) | 162 | if (clk->parent_periph) |
149 | mturate = clk_get_rate(clk->parent_periph); | 163 | mturate = clk_get_rate(clk->parent_periph); |
@@ -153,45 +167,6 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
153 | /* We need to be connected SOMEWHERE */ | 167 | /* We need to be connected SOMEWHERE */ |
154 | BUG(); | 168 | BUG(); |
155 | 169 | ||
156 | /* | ||
157 | * Are we in doze mode? | ||
158 | * In this mode the parent peripheral or the fixed 32768 Hz | ||
159 | * clock is fed into the block. | ||
160 | */ | ||
161 | if (!(tcr & PRCM_TCR_DOZE_MODE)) { | ||
162 | /* | ||
163 | * Here we're using the clock input from the APE ULP | ||
164 | * clock domain. But first: are the timers stopped? | ||
165 | */ | ||
166 | if (tcr & PRCM_TCR_STOPPED) { | ||
167 | clk32k = 0; | ||
168 | mturate = 0; | ||
169 | } else { | ||
170 | /* Else default mode: 0 and 2.4 MHz */ | ||
171 | clk32k = 0; | ||
172 | if (cpu_is_u5500()) | ||
173 | /* DB5500 divides by 8 */ | ||
174 | mturate /= 8; | ||
175 | else if (cpu_is_u8500ed()) { | ||
176 | /* | ||
177 | * This clocking setting must not be used | ||
178 | * in the ED chip, it is simply not | ||
179 | * connected anywhere! | ||
180 | */ | ||
181 | mturate = 0; | ||
182 | BUG(); | ||
183 | } else | ||
184 | /* | ||
185 | * In this mode the ulp38m4 clock is divided | ||
186 | * by a factor 16, on the DB8500 typically | ||
187 | * 38400000 / 16 ~ 2.4 MHz. | ||
188 | * TODO: Replace the constant with a reference | ||
189 | * to the ULP source once this is modeled. | ||
190 | */ | ||
191 | mturate = 38400000 / 16; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /* Return the clock selected for this MTU */ | 170 | /* Return the clock selected for this MTU */ |
196 | if (tcr & (1 << mtu)) | 171 | if (tcr & (1 << mtu)) |
197 | retclk = clk32k; | 172 | retclk = clk32k; |
@@ -317,6 +292,7 @@ static struct clkops clk_prcc_ops = { | |||
317 | }; | 292 | }; |
318 | 293 | ||
319 | static struct clk clk_32khz = { | 294 | static struct clk clk_32khz = { |
295 | .name = "clk_32khz", | ||
320 | .rate = 32000, | 296 | .rate = 32000, |
321 | }; | 297 | }; |
322 | 298 | ||
@@ -366,94 +342,96 @@ static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */ | |||
366 | */ | 342 | */ |
367 | 343 | ||
368 | /* Peripheral Cluster #1 */ | 344 | /* Peripheral Cluster #1 */ |
369 | static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); | 345 | static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); |
370 | static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); | 346 | static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); |
371 | static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); | 347 | static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); |
372 | static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); | 348 | static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); |
373 | static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL); | 349 | static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL); |
374 | static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); | 350 | static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); |
375 | static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); | 351 | static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); |
376 | static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); | 352 | static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); |
377 | static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk); | 353 | static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk); |
378 | static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); | 354 | static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); |
379 | static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); | 355 | static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); |
380 | static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); | 356 | static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); |
381 | static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); | 357 | static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); |
382 | 358 | ||
383 | /* Peripheral Cluster #2 */ | 359 | /* Peripheral Cluster #2 */ |
384 | 360 | ||
385 | static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); | 361 | static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); |
386 | static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); | 362 | static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); |
387 | static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); | 363 | static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); |
388 | static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); | 364 | static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); |
389 | static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); | 365 | static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); |
390 | static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); | 366 | static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); |
391 | static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); | 367 | static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); |
392 | static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); | 368 | static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); |
393 | static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); | 369 | static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); |
394 | static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); | 370 | static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); |
395 | static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); | 371 | static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); |
396 | static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk); | 372 | static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk); |
397 | 373 | ||
398 | static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL); | 374 | static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL); |
399 | static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL); | 375 | static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL); |
400 | static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL); | 376 | static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL); |
401 | static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL); | 377 | static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL); |
402 | static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk); | 378 | static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk); |
403 | static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk); | 379 | static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk); |
404 | static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk); | 380 | static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk); |
405 | static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk); | 381 | static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk); |
406 | static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL); | 382 | static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL); |
407 | static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL); | 383 | static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL); |
408 | static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL); | 384 | static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL); |
409 | static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk); | 385 | static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk); |
410 | 386 | ||
411 | /* Peripheral Cluster #3 */ | 387 | /* Peripheral Cluster #3 */ |
412 | static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); | 388 | static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); |
413 | static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); | 389 | static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); |
414 | static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); | 390 | static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); |
415 | static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); | 391 | static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); |
416 | static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); | 392 | static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); |
417 | static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); | 393 | static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); |
418 | static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); | 394 | static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); |
419 | static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); | 395 | static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); |
420 | static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk); | 396 | static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk); |
421 | static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk); | 397 | static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk); |
422 | static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); | 398 | static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); |
423 | 399 | ||
424 | /* Peripheral Cluster #4 is in the always on domain */ | 400 | /* Peripheral Cluster #4 is in the always on domain */ |
425 | 401 | ||
426 | /* Peripheral Cluster #5 */ | 402 | /* Peripheral Cluster #5 */ |
427 | static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); | 403 | static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); |
428 | static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); | 404 | static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); |
429 | static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); | 405 | static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); |
430 | 406 | ||
431 | /* Peripheral Cluster #6 */ | 407 | /* Peripheral Cluster #6 */ |
432 | 408 | ||
433 | /* MTU ID in data */ | 409 | /* MTU ID in data */ |
434 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); | 410 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); |
435 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); | 411 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); |
436 | static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); | 412 | static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); |
437 | static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); | 413 | static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); |
438 | static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); | 414 | static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); |
439 | static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); | 415 | static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); |
440 | static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL); | 416 | static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL); |
441 | static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); | 417 | static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); |
442 | static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); | 418 | static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); |
443 | static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); | 419 | static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); |
444 | static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); | 420 | static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); |
445 | static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); | 421 | static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); |
446 | 422 | ||
447 | /* Peripheral Cluster #7 */ | 423 | /* Peripheral Cluster #7 */ |
448 | 424 | ||
449 | static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); | 425 | static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); |
450 | /* MTU ID in data */ | 426 | /* MTU ID in data */ |
451 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); | 427 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); |
452 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); | 428 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); |
453 | static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); | 429 | static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); |
454 | static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); | 430 | static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); |
455 | 431 | ||
456 | static struct clk clk_dummy_apb_pclk; | 432 | static struct clk clk_dummy_apb_pclk = { |
433 | .name = "apb_pclk", | ||
434 | }; | ||
457 | 435 | ||
458 | static struct clk_lookup u8500_common_clks[] = { | 436 | static struct clk_lookup u8500_common_clks[] = { |
459 | CLK(dummy_apb_pclk, NULL, "apb_pclk"), | 437 | CLK(dummy_apb_pclk, NULL, "apb_pclk"), |
@@ -554,7 +532,7 @@ static struct clk_lookup u8500_ed_clks[] = { | |||
554 | 532 | ||
555 | static struct clk_lookup u8500_v1_clks[] = { | 533 | static struct clk_lookup u8500_v1_clks[] = { |
556 | /* Peripheral Cluster #1 */ | 534 | /* Peripheral Cluster #1 */ |
557 | CLK(i2c4, "nmk-i2c.4", NULL), | 535 | CLK(i2c4, "nmk-i2c.4", NULL), |
558 | CLK(spi3_v1, "spi3", NULL), | 536 | CLK(spi3_v1, "spi3", NULL), |
559 | CLK(msp1_v1, "msp1", NULL), | 537 | CLK(msp1_v1, "msp1", NULL), |
560 | 538 | ||
@@ -599,6 +577,183 @@ static struct clk_lookup u8500_v1_clks[] = { | |||
599 | CLK(uiccclk, "uicc", NULL), | 577 | CLK(uiccclk, "uicc", NULL), |
600 | }; | 578 | }; |
601 | 579 | ||
580 | #ifdef CONFIG_DEBUG_FS | ||
581 | /* | ||
582 | * debugfs support to trace clock tree hierarchy and attributes with | ||
583 | * powerdebug | ||
584 | */ | ||
585 | static struct dentry *clk_debugfs_root; | ||
586 | |||
587 | void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num) | ||
588 | { | ||
589 | while (num--) { | ||
590 | /* Check that the clock has not been already registered */ | ||
591 | if (!(cl->clk->list.prev != cl->clk->list.next)) | ||
592 | list_add_tail(&cl->clk->list, &clk_list); | ||
593 | |||
594 | cl++; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | static ssize_t usecount_dbg_read(struct file *file, char __user *buf, | ||
599 | size_t size, loff_t *off) | ||
600 | { | ||
601 | struct clk *clk = file->f_dentry->d_inode->i_private; | ||
602 | char cusecount[128]; | ||
603 | unsigned int len; | ||
604 | |||
605 | len = sprintf(cusecount, "%u\n", clk->enabled); | ||
606 | return simple_read_from_buffer(buf, size, off, cusecount, len); | ||
607 | } | ||
608 | |||
609 | static ssize_t rate_dbg_read(struct file *file, char __user *buf, | ||
610 | size_t size, loff_t *off) | ||
611 | { | ||
612 | struct clk *clk = file->f_dentry->d_inode->i_private; | ||
613 | char crate[128]; | ||
614 | unsigned int rate; | ||
615 | unsigned int len; | ||
616 | |||
617 | rate = clk_get_rate(clk); | ||
618 | len = sprintf(crate, "%u\n", rate); | ||
619 | return simple_read_from_buffer(buf, size, off, crate, len); | ||
620 | } | ||
621 | |||
622 | static const struct file_operations usecount_fops = { | ||
623 | .read = usecount_dbg_read, | ||
624 | }; | ||
625 | |||
626 | static const struct file_operations set_rate_fops = { | ||
627 | .read = rate_dbg_read, | ||
628 | }; | ||
629 | |||
630 | static struct dentry *clk_debugfs_register_dir(struct clk *c, | ||
631 | struct dentry *p_dentry) | ||
632 | { | ||
633 | struct dentry *d, *clk_d, *child, *child_tmp; | ||
634 | char s[255]; | ||
635 | char *p = s; | ||
636 | |||
637 | if (c->name == NULL) | ||
638 | p += sprintf(p, "BUG"); | ||
639 | else | ||
640 | p += sprintf(p, "%s", c->name); | ||
641 | |||
642 | clk_d = debugfs_create_dir(s, p_dentry); | ||
643 | if (!clk_d) | ||
644 | return NULL; | ||
645 | |||
646 | d = debugfs_create_file("usecount", S_IRUGO, | ||
647 | clk_d, c, &usecount_fops); | ||
648 | if (!d) | ||
649 | goto err_out; | ||
650 | d = debugfs_create_file("rate", S_IRUGO, | ||
651 | clk_d, c, &set_rate_fops); | ||
652 | if (!d) | ||
653 | goto err_out; | ||
654 | /* | ||
655 | * TODO : not currently available in ux500 | ||
656 | * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags); | ||
657 | * if (!d) | ||
658 | * goto err_out; | ||
659 | */ | ||
660 | |||
661 | return clk_d; | ||
662 | |||
663 | err_out: | ||
664 | d = clk_d; | ||
665 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | ||
666 | debugfs_remove(child); | ||
667 | debugfs_remove(clk_d); | ||
668 | return NULL; | ||
669 | } | ||
670 | |||
671 | static void clk_debugfs_remove_dir(struct dentry *cdentry) | ||
672 | { | ||
673 | struct dentry *d, *child, *child_tmp; | ||
674 | |||
675 | d = cdentry; | ||
676 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | ||
677 | debugfs_remove(child); | ||
678 | debugfs_remove(cdentry); | ||
679 | return ; | ||
680 | } | ||
681 | |||
682 | static int clk_debugfs_register_one(struct clk *c) | ||
683 | { | ||
684 | struct clk *pa = c->parent_periph; | ||
685 | struct clk *bpa = c->parent_cluster; | ||
686 | |||
687 | if (!(bpa && !pa)) { | ||
688 | c->dent = clk_debugfs_register_dir(c, | ||
689 | pa ? pa->dent : clk_debugfs_root); | ||
690 | if (!c->dent) | ||
691 | return -ENOMEM; | ||
692 | } | ||
693 | |||
694 | if (bpa) { | ||
695 | c->dent_bus = clk_debugfs_register_dir(c, | ||
696 | bpa->dent_bus ? bpa->dent_bus : bpa->dent); | ||
697 | if ((!c->dent_bus) && (c->dent)) { | ||
698 | clk_debugfs_remove_dir(c->dent); | ||
699 | c->dent = NULL; | ||
700 | return -ENOMEM; | ||
701 | } | ||
702 | } | ||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static int clk_debugfs_register(struct clk *c) | ||
707 | { | ||
708 | int err; | ||
709 | struct clk *pa = c->parent_periph; | ||
710 | struct clk *bpa = c->parent_cluster; | ||
711 | |||
712 | if (pa && (!pa->dent && !pa->dent_bus)) { | ||
713 | err = clk_debugfs_register(pa); | ||
714 | if (err) | ||
715 | return err; | ||
716 | } | ||
717 | |||
718 | if (bpa && (!bpa->dent && !bpa->dent_bus)) { | ||
719 | err = clk_debugfs_register(bpa); | ||
720 | if (err) | ||
721 | return err; | ||
722 | } | ||
723 | |||
724 | if ((!c->dent) && (!c->dent_bus)) { | ||
725 | err = clk_debugfs_register_one(c); | ||
726 | if (err) | ||
727 | return err; | ||
728 | } | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | static int __init clk_debugfs_init(void) | ||
733 | { | ||
734 | struct clk *c; | ||
735 | struct dentry *d; | ||
736 | int err; | ||
737 | |||
738 | d = debugfs_create_dir("clock", NULL); | ||
739 | if (!d) | ||
740 | return -ENOMEM; | ||
741 | clk_debugfs_root = d; | ||
742 | |||
743 | list_for_each_entry(c, &clk_list, list) { | ||
744 | err = clk_debugfs_register(c); | ||
745 | if (err) | ||
746 | goto err_out; | ||
747 | } | ||
748 | return 0; | ||
749 | err_out: | ||
750 | debugfs_remove_recursive(clk_debugfs_root); | ||
751 | return err; | ||
752 | } | ||
753 | |||
754 | late_initcall(clk_debugfs_init); | ||
755 | #endif /* defined(CONFIG_DEBUG_FS) */ | ||
756 | |||
602 | int __init clk_init(void) | 757 | int __init clk_init(void) |
603 | { | 758 | { |
604 | if (cpu_is_u8500ed()) { | 759 | if (cpu_is_u8500ed()) { |
@@ -609,7 +764,8 @@ int __init clk_init(void) | |||
609 | /* Clock tree for U5500 not implemented yet */ | 764 | /* Clock tree for U5500 not implemented yet */ |
610 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; | 765 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; |
611 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; | 766 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; |
612 | clk_per6clk.rate = 26000000; | 767 | clk_uartclk.rate = 36360000; |
768 | clk_sdmmcclk.rate = 99900000; | ||
613 | } | 769 | } |
614 | 770 | ||
615 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | 771 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); |
@@ -618,5 +774,12 @@ int __init clk_init(void) | |||
618 | else | 774 | else |
619 | clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | 775 | clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); |
620 | 776 | ||
777 | #ifdef CONFIG_DEBUG_FS | ||
778 | clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | ||
779 | if (cpu_is_u8500ed()) | ||
780 | clk_debugfs_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks)); | ||
781 | else | ||
782 | clk_debugfs_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | ||
783 | #endif | ||
621 | return 0; | 784 | return 0; |
622 | } | 785 | } |
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h index a05802501527..074490705229 100644 --- a/arch/arm/mach-ux500/clock.h +++ b/arch/arm/mach-ux500/clock.h | |||
@@ -90,6 +90,10 @@ struct clk { | |||
90 | 90 | ||
91 | struct clk *parent_cluster; | 91 | struct clk *parent_cluster; |
92 | struct clk *parent_periph; | 92 | struct clk *parent_periph; |
93 | #if defined(CONFIG_DEBUG_FS) | ||
94 | struct dentry *dent; /* For visible tree hierarchy */ | ||
95 | struct dentry *dent_bus; /* For visible tree hierarchy */ | ||
96 | #endif | ||
93 | }; | 97 | }; |
94 | 98 | ||
95 | #define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \ | 99 | #define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \ |
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 2f87075e9d6f..acc841e48de4 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c | |||
@@ -8,14 +8,19 @@ | |||
8 | #include <linux/platform_device.h> | 8 | #include <linux/platform_device.h> |
9 | #include <linux/amba/bus.h> | 9 | #include <linux/amba/bus.h> |
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/irq.h> | ||
11 | 12 | ||
12 | #include <asm/mach/map.h> | 13 | #include <asm/mach/map.h> |
13 | 14 | ||
15 | #include <plat/gpio.h> | ||
16 | |||
14 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
15 | #include <mach/devices.h> | 18 | #include <mach/devices.h> |
16 | #include <mach/setup.h> | 19 | #include <mach/setup.h> |
17 | #include <mach/irqs.h> | 20 | #include <mach/irqs.h> |
18 | 21 | ||
22 | #include "devices-db5500.h" | ||
23 | |||
19 | static struct map_desc u5500_io_desc[] __initdata = { | 24 | static struct map_desc u5500_io_desc[] __initdata = { |
20 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), | 25 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), |
21 | __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), | 26 | __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), |
@@ -110,19 +115,32 @@ static struct platform_device mbox2_device = { | |||
110 | }; | 115 | }; |
111 | 116 | ||
112 | static struct platform_device *u5500_platform_devs[] __initdata = { | 117 | static struct platform_device *u5500_platform_devs[] __initdata = { |
113 | &u5500_gpio_devs[0], | ||
114 | &u5500_gpio_devs[1], | ||
115 | &u5500_gpio_devs[2], | ||
116 | &u5500_gpio_devs[3], | ||
117 | &u5500_gpio_devs[4], | ||
118 | &u5500_gpio_devs[5], | ||
119 | &u5500_gpio_devs[6], | ||
120 | &u5500_gpio_devs[7], | ||
121 | &mbox0_device, | 118 | &mbox0_device, |
122 | &mbox1_device, | 119 | &mbox1_device, |
123 | &mbox2_device, | 120 | &mbox2_device, |
124 | }; | 121 | }; |
125 | 122 | ||
123 | static resource_size_t __initdata db5500_gpio_base[] = { | ||
124 | U5500_GPIOBANK0_BASE, | ||
125 | U5500_GPIOBANK1_BASE, | ||
126 | U5500_GPIOBANK2_BASE, | ||
127 | U5500_GPIOBANK3_BASE, | ||
128 | U5500_GPIOBANK4_BASE, | ||
129 | U5500_GPIOBANK5_BASE, | ||
130 | U5500_GPIOBANK6_BASE, | ||
131 | U5500_GPIOBANK7_BASE, | ||
132 | }; | ||
133 | |||
134 | static void __init db5500_add_gpios(void) | ||
135 | { | ||
136 | struct nmk_gpio_platform_data pdata = { | ||
137 | /* No custom data yet */ | ||
138 | }; | ||
139 | |||
140 | dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base), | ||
141 | IRQ_DB5500_GPIO0, &pdata); | ||
142 | } | ||
143 | |||
126 | void __init u5500_map_io(void) | 144 | void __init u5500_map_io(void) |
127 | { | 145 | { |
128 | ux500_map_io(); | 146 | ux500_map_io(); |
@@ -132,7 +150,9 @@ void __init u5500_map_io(void) | |||
132 | 150 | ||
133 | void __init u5500_init_devices(void) | 151 | void __init u5500_init_devices(void) |
134 | { | 152 | { |
135 | ux500_init_devices(); | 153 | db5500_add_gpios(); |
154 | db5500_dma_init(); | ||
155 | db5500_add_rtc(); | ||
136 | 156 | ||
137 | platform_add_devices(u5500_platform_devs, | 157 | platform_add_devices(u5500_platform_devs, |
138 | ARRAY_SIZE(u5500_platform_devs)); | 158 | ARRAY_SIZE(u5500_platform_devs)); |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 4acab7544b3c..c0f34a404c53 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -22,23 +22,15 @@ | |||
22 | #include <mach/setup.h> | 22 | #include <mach/setup.h> |
23 | #include <mach/devices.h> | 23 | #include <mach/devices.h> |
24 | 24 | ||
25 | #include "devices-db8500.h" | ||
26 | |||
25 | static struct platform_device *platform_devs[] __initdata = { | 27 | static struct platform_device *platform_devs[] __initdata = { |
26 | &u8500_gpio_devs[0], | ||
27 | &u8500_gpio_devs[1], | ||
28 | &u8500_gpio_devs[2], | ||
29 | &u8500_gpio_devs[3], | ||
30 | &u8500_gpio_devs[4], | ||
31 | &u8500_gpio_devs[5], | ||
32 | &u8500_gpio_devs[6], | ||
33 | &u8500_gpio_devs[7], | ||
34 | &u8500_gpio_devs[8], | ||
35 | &u8500_dma40_device, | 28 | &u8500_dma40_device, |
36 | }; | 29 | }; |
37 | 30 | ||
38 | /* minimum static i/o mapping required to boot U8500 platforms */ | 31 | /* minimum static i/o mapping required to boot U8500 platforms */ |
39 | static struct map_desc u8500_io_desc[] __initdata = { | 32 | static struct map_desc u8500_io_desc[] __initdata = { |
40 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), | 33 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), |
41 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), | ||
42 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), | 34 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), |
43 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), | 35 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), |
44 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), | 36 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), |
@@ -46,13 +38,18 @@ static struct map_desc u8500_io_desc[] __initdata = { | |||
46 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), | 38 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), |
47 | }; | 39 | }; |
48 | 40 | ||
49 | static struct map_desc u8500ed_io_desc[] __initdata = { | 41 | static struct map_desc u8500_ed_io_desc[] __initdata = { |
50 | __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), | 42 | __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K), |
51 | __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), | 43 | __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K), |
52 | }; | 44 | }; |
53 | 45 | ||
54 | static struct map_desc u8500v1_io_desc[] __initdata = { | 46 | static struct map_desc u8500_v1_io_desc[] __initdata = { |
55 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), | 47 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), |
48 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE_V1, SZ_4K), | ||
49 | }; | ||
50 | |||
51 | static struct map_desc u8500_v2_io_desc[] __initdata = { | ||
52 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), | ||
56 | }; | 53 | }; |
57 | 54 | ||
58 | /* | 55 | /* |
@@ -125,14 +122,38 @@ void __init u8500_map_io(void) | |||
125 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); | 122 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); |
126 | 123 | ||
127 | if (cpu_is_u8500ed()) | 124 | if (cpu_is_u8500ed()) |
128 | iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); | 125 | iotable_init(u8500_ed_io_desc, ARRAY_SIZE(u8500_ed_io_desc)); |
129 | else | 126 | else if (cpu_is_u8500v1()) |
130 | iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); | 127 | iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc)); |
128 | else if (cpu_is_u8500v2()) | ||
129 | iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); | ||
131 | 130 | ||
132 | /* Read out the ASIC ID as early as we can */ | 131 | /* Read out the ASIC ID as early as we can */ |
133 | get_db8500_asic_id(); | 132 | get_db8500_asic_id(); |
134 | } | 133 | } |
135 | 134 | ||
135 | static resource_size_t __initdata db8500_gpio_base[] = { | ||
136 | U8500_GPIOBANK0_BASE, | ||
137 | U8500_GPIOBANK1_BASE, | ||
138 | U8500_GPIOBANK2_BASE, | ||
139 | U8500_GPIOBANK3_BASE, | ||
140 | U8500_GPIOBANK4_BASE, | ||
141 | U8500_GPIOBANK5_BASE, | ||
142 | U8500_GPIOBANK6_BASE, | ||
143 | U8500_GPIOBANK7_BASE, | ||
144 | U8500_GPIOBANK8_BASE, | ||
145 | }; | ||
146 | |||
147 | static void __init db8500_add_gpios(void) | ||
148 | { | ||
149 | struct nmk_gpio_platform_data pdata = { | ||
150 | /* No custom data yet */ | ||
151 | }; | ||
152 | |||
153 | dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base), | ||
154 | IRQ_DB8500_GPIO0, &pdata); | ||
155 | } | ||
156 | |||
136 | /* | 157 | /* |
137 | * This function is called from the board init | 158 | * This function is called from the board init |
138 | */ | 159 | */ |
@@ -152,12 +173,13 @@ void __init u8500_init_devices(void) | |||
152 | else | 173 | else |
153 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); | 174 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); |
154 | 175 | ||
155 | ux500_init_devices(); | ||
156 | |||
157 | if (cpu_is_u8500ed()) | 176 | if (cpu_is_u8500ed()) |
158 | dma40_u8500ed_fixup(); | 177 | dma40_u8500ed_fixup(); |
159 | 178 | ||
160 | /* Register the platform devices */ | 179 | db8500_add_rtc(); |
180 | db8500_add_gpios(); | ||
181 | |||
182 | platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); | ||
161 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 183 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
162 | 184 | ||
163 | return ; | 185 | return ; |
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 608a1372b172..a3700bc374d3 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/platform_device.h> | 8 | #include <linux/platform_device.h> |
9 | #include <linux/amba/bus.h> | ||
10 | #include <linux/io.h> | 9 | #include <linux/io.h> |
11 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
12 | 11 | ||
@@ -20,6 +19,7 @@ | |||
20 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
21 | #include <mach/setup.h> | 20 | #include <mach/setup.h> |
22 | #include <mach/devices.h> | 21 | #include <mach/devices.h> |
22 | #include <mach/prcmu.h> | ||
23 | 23 | ||
24 | #include "clock.h" | 24 | #include "clock.h" |
25 | 25 | ||
@@ -45,20 +45,11 @@ static struct map_desc ux500_io_desc[] __initdata = { | |||
45 | __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), | 45 | __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static struct amba_device *ux500_amba_devs[] __initdata = { | ||
49 | &ux500_pl031_device, | ||
50 | }; | ||
51 | |||
52 | void __init ux500_map_io(void) | 48 | void __init ux500_map_io(void) |
53 | { | 49 | { |
54 | iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); | 50 | iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); |
55 | } | 51 | } |
56 | 52 | ||
57 | void __init ux500_init_devices(void) | ||
58 | { | ||
59 | amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs)); | ||
60 | } | ||
61 | |||
62 | void __init ux500_init_irq(void) | 53 | void __init ux500_init_irq(void) |
63 | { | 54 | { |
64 | gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); | 55 | gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); |
@@ -68,6 +59,8 @@ void __init ux500_init_irq(void) | |||
68 | * Init clocks here so that they are available for system timer | 59 | * Init clocks here so that they are available for system timer |
69 | * initialization. | 60 | * initialization. |
70 | */ | 61 | */ |
62 | if (cpu_is_u8500()) | ||
63 | prcmu_early_init(); | ||
71 | clk_init(); | 64 | clk_init(); |
72 | } | 65 | } |
73 | 66 | ||
diff --git a/arch/arm/mach-ux500/cpufreq.c b/arch/arm/mach-ux500/cpufreq.c new file mode 100644 index 000000000000..5c5b747f134d --- /dev/null +++ b/arch/arm/mach-ux500/cpufreq.c | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * CPU frequency scaling for u8500 | ||
3 | * Inspired by linux/arch/arm/mach-davinci/cpufreq.c | ||
4 | * | ||
5 | * Copyright (C) STMicroelectronics 2009 | ||
6 | * Copyright (C) ST-Ericsson SA 2010 | ||
7 | * | ||
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
11 | * Author: Martin Persson <martin.persson@stericsson.com> | ||
12 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/cpufreq.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | #include <mach/hardware.h> | ||
22 | #include <mach/prcmu.h> | ||
23 | #include <mach/prcmu-defs.h> | ||
24 | |||
25 | #define DRIVER_NAME "cpufreq-u8500" | ||
26 | #define CPUFREQ_NAME "u8500" | ||
27 | |||
28 | static struct device *dev; | ||
29 | |||
30 | static struct cpufreq_frequency_table freq_table[] = { | ||
31 | [0] = { | ||
32 | .index = 0, | ||
33 | .frequency = 200000, | ||
34 | }, | ||
35 | [1] = { | ||
36 | .index = 1, | ||
37 | .frequency = 300000, | ||
38 | }, | ||
39 | [2] = { | ||
40 | .index = 2, | ||
41 | .frequency = 600000, | ||
42 | }, | ||
43 | [3] = { | ||
44 | /* Used for CPU_OPP_MAX, if available */ | ||
45 | .index = 3, | ||
46 | .frequency = CPUFREQ_TABLE_END, | ||
47 | }, | ||
48 | [4] = { | ||
49 | .index = 4, | ||
50 | .frequency = CPUFREQ_TABLE_END, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static enum prcmu_cpu_opp index2opp[] = { | ||
55 | CPU_OPP_EXT_CLK, | ||
56 | CPU_OPP_50, | ||
57 | CPU_OPP_100, | ||
58 | CPU_OPP_MAX | ||
59 | }; | ||
60 | |||
61 | static int u8500_cpufreq_verify_speed(struct cpufreq_policy *policy) | ||
62 | { | ||
63 | return cpufreq_frequency_table_verify(policy, freq_table); | ||
64 | } | ||
65 | |||
66 | static int u8500_cpufreq_target(struct cpufreq_policy *policy, | ||
67 | unsigned int target_freq, | ||
68 | unsigned int relation) | ||
69 | { | ||
70 | struct cpufreq_freqs freqs; | ||
71 | unsigned int index; | ||
72 | int ret = 0; | ||
73 | |||
74 | /* | ||
75 | * Ensure desired rate is within allowed range. Some govenors | ||
76 | * (ondemand) will just pass target_freq=0 to get the minimum. | ||
77 | */ | ||
78 | if (target_freq < policy->cpuinfo.min_freq) | ||
79 | target_freq = policy->cpuinfo.min_freq; | ||
80 | if (target_freq > policy->cpuinfo.max_freq) | ||
81 | target_freq = policy->cpuinfo.max_freq; | ||
82 | |||
83 | ret = cpufreq_frequency_table_target(policy, freq_table, | ||
84 | target_freq, relation, &index); | ||
85 | if (ret < 0) { | ||
86 | dev_err(dev, "Could not look up next frequency\n"); | ||
87 | return ret; | ||
88 | } | ||
89 | |||
90 | freqs.old = policy->cur; | ||
91 | freqs.new = freq_table[index].frequency; | ||
92 | freqs.cpu = policy->cpu; | ||
93 | |||
94 | if (freqs.old == freqs.new) { | ||
95 | dev_dbg(dev, "Current and target frequencies are equal\n"); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | dev_dbg(dev, "transition: %u --> %u\n", freqs.old, freqs.new); | ||
100 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
101 | |||
102 | ret = prcmu_set_cpu_opp(index2opp[index]); | ||
103 | if (ret < 0) { | ||
104 | dev_err(dev, "Failed to set OPP level\n"); | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
109 | |||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | static unsigned int u8500_cpufreq_getspeed(unsigned int cpu) | ||
114 | { | ||
115 | int i; | ||
116 | |||
117 | for (i = 0; prcmu_get_cpu_opp() != index2opp[i]; i++) | ||
118 | ; | ||
119 | return freq_table[i].frequency; | ||
120 | } | ||
121 | |||
122 | static int __cpuinit u8500_cpu_init(struct cpufreq_policy *policy) | ||
123 | { | ||
124 | int res; | ||
125 | |||
126 | BUILD_BUG_ON(ARRAY_SIZE(index2opp) + 1 != ARRAY_SIZE(freq_table)); | ||
127 | |||
128 | if (cpu_is_u8500v2()) { | ||
129 | freq_table[1].frequency = 400000; | ||
130 | freq_table[2].frequency = 800000; | ||
131 | if (prcmu_has_arm_maxopp()) | ||
132 | freq_table[3].frequency = 1000000; | ||
133 | } | ||
134 | |||
135 | /* get policy fields based on the table */ | ||
136 | res = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
137 | if (!res) | ||
138 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
139 | else { | ||
140 | dev_err(dev, "u8500-cpufreq : Failed to read policy table\n"); | ||
141 | return res; | ||
142 | } | ||
143 | |||
144 | policy->min = policy->cpuinfo.min_freq; | ||
145 | policy->max = policy->cpuinfo.max_freq; | ||
146 | policy->cur = u8500_cpufreq_getspeed(policy->cpu); | ||
147 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
148 | |||
149 | /* | ||
150 | * FIXME : Need to take time measurement across the target() | ||
151 | * function with no/some/all drivers in the notification | ||
152 | * list. | ||
153 | */ | ||
154 | policy->cpuinfo.transition_latency = 200 * 1000; /* in ns */ | ||
155 | |||
156 | /* policy sharing between dual CPUs */ | ||
157 | cpumask_copy(policy->cpus, &cpu_present_map); | ||
158 | |||
159 | policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; | ||
160 | |||
161 | return res; | ||
162 | } | ||
163 | |||
164 | static struct freq_attr *u8500_cpufreq_attr[] = { | ||
165 | &cpufreq_freq_attr_scaling_available_freqs, | ||
166 | NULL, | ||
167 | }; | ||
168 | static int u8500_cpu_exit(struct cpufreq_policy *policy) | ||
169 | { | ||
170 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static struct cpufreq_driver u8500_driver = { | ||
175 | .owner = THIS_MODULE, | ||
176 | .flags = CPUFREQ_STICKY, | ||
177 | .verify = u8500_cpufreq_verify_speed, | ||
178 | .target = u8500_cpufreq_target, | ||
179 | .get = u8500_cpufreq_getspeed, | ||
180 | .init = u8500_cpu_init, | ||
181 | .exit = u8500_cpu_exit, | ||
182 | .name = CPUFREQ_NAME, | ||
183 | .attr = u8500_cpufreq_attr, | ||
184 | }; | ||
185 | |||
186 | static int __init u8500_cpufreq_probe(struct platform_device *pdev) | ||
187 | { | ||
188 | dev = &pdev->dev; | ||
189 | return cpufreq_register_driver(&u8500_driver); | ||
190 | } | ||
191 | |||
192 | static int __exit u8500_cpufreq_remove(struct platform_device *pdev) | ||
193 | { | ||
194 | return cpufreq_unregister_driver(&u8500_driver); | ||
195 | } | ||
196 | |||
197 | static struct platform_driver u8500_cpufreq_driver = { | ||
198 | .driver = { | ||
199 | .name = DRIVER_NAME, | ||
200 | .owner = THIS_MODULE, | ||
201 | }, | ||
202 | .remove = __exit_p(u8500_cpufreq_remove), | ||
203 | }; | ||
204 | |||
205 | static int __init u8500_cpufreq_init(void) | ||
206 | { | ||
207 | return platform_driver_probe(&u8500_cpufreq_driver, | ||
208 | &u8500_cpufreq_probe); | ||
209 | } | ||
210 | |||
211 | device_initcall(u8500_cpufreq_init); | ||
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c new file mode 100644 index 000000000000..fe69f5fac1bb --- /dev/null +++ b/arch/arm/mach-ux500/devices-common.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/dma-mapping.h> | ||
10 | #include <linux/err.h> | ||
11 | #include <linux/irq.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/amba/bus.h> | ||
15 | |||
16 | #include <plat/gpio.h> | ||
17 | |||
18 | #include <mach/hardware.h> | ||
19 | |||
20 | #include "devices-common.h" | ||
21 | |||
22 | struct amba_device * | ||
23 | dbx500_add_amba_device(const char *name, resource_size_t base, | ||
24 | int irq, void *pdata, unsigned int periphid) | ||
25 | { | ||
26 | struct amba_device *dev; | ||
27 | int ret; | ||
28 | |||
29 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | ||
30 | if (!dev) | ||
31 | return ERR_PTR(-ENOMEM); | ||
32 | |||
33 | dev->dev.init_name = name; | ||
34 | |||
35 | dev->res.start = base; | ||
36 | dev->res.end = base + SZ_4K - 1; | ||
37 | dev->res.flags = IORESOURCE_MEM; | ||
38 | |||
39 | dev->dma_mask = DMA_BIT_MASK(32); | ||
40 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
41 | |||
42 | dev->irq[0] = irq; | ||
43 | dev->irq[1] = NO_IRQ; | ||
44 | |||
45 | dev->periphid = periphid; | ||
46 | |||
47 | dev->dev.platform_data = pdata; | ||
48 | |||
49 | ret = amba_device_register(dev, &iomem_resource); | ||
50 | if (ret) { | ||
51 | kfree(dev); | ||
52 | return ERR_PTR(ret); | ||
53 | } | ||
54 | |||
55 | return dev; | ||
56 | } | ||
57 | |||
58 | static struct platform_device * | ||
59 | dbx500_add_platform_device(const char *name, int id, void *pdata, | ||
60 | struct resource *res, int resnum) | ||
61 | { | ||
62 | struct platform_device *dev; | ||
63 | int ret; | ||
64 | |||
65 | dev = platform_device_alloc(name, id); | ||
66 | if (!dev) | ||
67 | return ERR_PTR(-ENOMEM); | ||
68 | |||
69 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
70 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; | ||
71 | |||
72 | ret = platform_device_add_resources(dev, res, resnum); | ||
73 | if (ret) | ||
74 | goto out_free; | ||
75 | |||
76 | dev->dev.platform_data = pdata; | ||
77 | |||
78 | ret = platform_device_add(dev); | ||
79 | if (ret) | ||
80 | goto out_free; | ||
81 | |||
82 | return dev; | ||
83 | |||
84 | out_free: | ||
85 | platform_device_put(dev); | ||
86 | return ERR_PTR(ret); | ||
87 | } | ||
88 | |||
89 | struct platform_device * | ||
90 | dbx500_add_platform_device_4k1irq(const char *name, int id, | ||
91 | resource_size_t base, | ||
92 | int irq, void *pdata) | ||
93 | { | ||
94 | struct resource resources[] = { | ||
95 | [0] = { | ||
96 | .start = base, | ||
97 | .end = base + SZ_4K - 1, | ||
98 | .flags = IORESOURCE_MEM, | ||
99 | }, | ||
100 | [1] = { | ||
101 | .start = irq, | ||
102 | .end = irq, | ||
103 | .flags = IORESOURCE_IRQ, | ||
104 | } | ||
105 | }; | ||
106 | |||
107 | return dbx500_add_platform_device(name, id, pdata, resources, | ||
108 | ARRAY_SIZE(resources)); | ||
109 | } | ||
110 | |||
111 | static struct platform_device * | ||
112 | dbx500_add_gpio(int id, resource_size_t addr, int irq, | ||
113 | struct nmk_gpio_platform_data *pdata) | ||
114 | { | ||
115 | struct resource resources[] = { | ||
116 | { | ||
117 | .start = addr, | ||
118 | .end = addr + 127, | ||
119 | .flags = IORESOURCE_MEM, | ||
120 | }, | ||
121 | { | ||
122 | .start = irq, | ||
123 | .end = irq, | ||
124 | .flags = IORESOURCE_IRQ, | ||
125 | } | ||
126 | }; | ||
127 | |||
128 | return platform_device_register_resndata(NULL, "gpio", id, | ||
129 | resources, ARRAY_SIZE(resources), | ||
130 | pdata, sizeof(*pdata)); | ||
131 | } | ||
132 | |||
133 | void dbx500_add_gpios(resource_size_t *base, int num, int irq, | ||
134 | struct nmk_gpio_platform_data *pdata) | ||
135 | { | ||
136 | int first = 0; | ||
137 | int i; | ||
138 | |||
139 | for (i = 0; i < num; i++, first += 32, irq++) { | ||
140 | pdata->first_gpio = first; | ||
141 | pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); | ||
142 | |||
143 | dbx500_add_gpio(i, base[i], irq, pdata); | ||
144 | } | ||
145 | } | ||
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h new file mode 100644 index 000000000000..cbadc117d2db --- /dev/null +++ b/arch/arm/mach-ux500/devices-common.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #ifndef __DEVICES_COMMON_H | ||
9 | #define __DEVICES_COMMON_H | ||
10 | |||
11 | extern struct amba_device * | ||
12 | dbx500_add_amba_device(const char *name, resource_size_t base, | ||
13 | int irq, void *pdata, unsigned int periphid); | ||
14 | |||
15 | extern struct platform_device * | ||
16 | dbx500_add_platform_device_4k1irq(const char *name, int id, | ||
17 | resource_size_t base, | ||
18 | int irq, void *pdata); | ||
19 | |||
20 | struct spi_master_cntlr; | ||
21 | |||
22 | static inline struct amba_device * | ||
23 | dbx500_add_msp_spi(const char *name, resource_size_t base, int irq, | ||
24 | struct spi_master_cntlr *pdata) | ||
25 | { | ||
26 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | ||
27 | } | ||
28 | |||
29 | static inline struct amba_device * | ||
30 | dbx500_add_spi(const char *name, resource_size_t base, int irq, | ||
31 | struct spi_master_cntlr *pdata) | ||
32 | { | ||
33 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | ||
34 | } | ||
35 | |||
36 | struct mmci_platform_data; | ||
37 | |||
38 | static inline struct amba_device * | ||
39 | dbx500_add_sdi(const char *name, resource_size_t base, int irq, | ||
40 | struct mmci_platform_data *pdata) | ||
41 | { | ||
42 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | ||
43 | } | ||
44 | |||
45 | static inline struct amba_device * | ||
46 | dbx500_add_uart(const char *name, resource_size_t base, int irq) | ||
47 | { | ||
48 | return dbx500_add_amba_device(name, base, irq, NULL, 0); | ||
49 | } | ||
50 | |||
51 | struct nmk_i2c_controller; | ||
52 | |||
53 | static inline struct platform_device * | ||
54 | dbx500_add_i2c(int id, resource_size_t base, int irq, | ||
55 | struct nmk_i2c_controller *pdata) | ||
56 | { | ||
57 | return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq, | ||
58 | pdata); | ||
59 | } | ||
60 | |||
61 | struct msp_i2s_platform_data; | ||
62 | |||
63 | static inline struct platform_device * | ||
64 | dbx500_add_msp_i2s(int id, resource_size_t base, int irq, | ||
65 | struct msp_i2s_platform_data *pdata) | ||
66 | { | ||
67 | return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq, | ||
68 | pdata); | ||
69 | } | ||
70 | |||
71 | static inline struct amba_device * | ||
72 | dbx500_add_rtc(resource_size_t base, int irq) | ||
73 | { | ||
74 | return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0); | ||
75 | } | ||
76 | |||
77 | struct nmk_gpio_platform_data; | ||
78 | |||
79 | void dbx500_add_gpios(resource_size_t *base, int num, int irq, | ||
80 | struct nmk_gpio_platform_data *pdata); | ||
81 | |||
82 | #endif | ||
diff --git a/arch/arm/mach-ux500/devices-db5500.c b/arch/arm/mach-ux500/devices-db5500.c deleted file mode 100644 index 33e5b56bebb6..000000000000 --- a/arch/arm/mach-ux500/devices-db5500.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/platform_device.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/gpio.h> | ||
11 | |||
12 | #include <mach/hardware.h> | ||
13 | #include <mach/devices.h> | ||
14 | |||
15 | static struct nmk_gpio_platform_data u5500_gpio_data[] = { | ||
16 | GPIO_DATA("GPIO-0-31", 0), | ||
17 | GPIO_DATA("GPIO-32-63", 32), /* 36..63 not routed to pin */ | ||
18 | GPIO_DATA("GPIO-64-95", 64), /* 83..95 not routed to pin */ | ||
19 | GPIO_DATA("GPIO-96-127", 96), /* 102..127 not routed to pin */ | ||
20 | GPIO_DATA("GPIO-128-159", 128), /* 149..159 not routed to pin */ | ||
21 | GPIO_DATA("GPIO-160-191", 160), | ||
22 | GPIO_DATA("GPIO-192-223", 192), | ||
23 | GPIO_DATA("GPIO-224-255", 224), /* 228..255 not routed to pin */ | ||
24 | }; | ||
25 | |||
26 | static struct resource u5500_gpio_resources[] = { | ||
27 | GPIO_RESOURCE(0), | ||
28 | GPIO_RESOURCE(1), | ||
29 | GPIO_RESOURCE(2), | ||
30 | GPIO_RESOURCE(3), | ||
31 | GPIO_RESOURCE(4), | ||
32 | GPIO_RESOURCE(5), | ||
33 | GPIO_RESOURCE(6), | ||
34 | GPIO_RESOURCE(7), | ||
35 | }; | ||
36 | |||
37 | struct platform_device u5500_gpio_devs[] = { | ||
38 | GPIO_DEVICE(0), | ||
39 | GPIO_DEVICE(1), | ||
40 | GPIO_DEVICE(2), | ||
41 | GPIO_DEVICE(3), | ||
42 | GPIO_DEVICE(4), | ||
43 | GPIO_DEVICE(5), | ||
44 | GPIO_DEVICE(6), | ||
45 | GPIO_DEVICE(7), | ||
46 | }; | ||
diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h new file mode 100644 index 000000000000..c8d7901c1f2d --- /dev/null +++ b/arch/arm/mach-ux500/devices-db5500.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #ifndef __DEVICES_DB5500_H | ||
9 | #define __DEVICES_DB5500_H | ||
10 | |||
11 | #include "devices-common.h" | ||
12 | |||
13 | #define db5500_add_i2c1(pdata) \ | ||
14 | dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) | ||
15 | #define db5500_add_i2c2(pdata) \ | ||
16 | dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) | ||
17 | #define db5500_add_i2c3(pdata) \ | ||
18 | dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) | ||
19 | |||
20 | #define db5500_add_msp0_i2s(pdata) \ | ||
21 | dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) | ||
22 | #define db5500_add_msp1_i2s(pdata) \ | ||
23 | dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) | ||
24 | #define db5500_add_msp2_i2s(pdata) \ | ||
25 | dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) | ||
26 | |||
27 | #define db5500_add_msp0_spi(pdata) \ | ||
28 | dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) | ||
29 | #define db5500_add_msp1_spi(pdata) \ | ||
30 | dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) | ||
31 | #define db5500_add_msp2_spi(pdata) \ | ||
32 | dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) | ||
33 | |||
34 | #define db5500_add_rtc() \ | ||
35 | dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC); | ||
36 | |||
37 | #define db5500_add_sdi0(pdata) \ | ||
38 | dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata) | ||
39 | #define db5500_add_sdi1(pdata) \ | ||
40 | dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata) | ||
41 | #define db5500_add_sdi2(pdata) \ | ||
42 | dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata) | ||
43 | #define db5500_add_sdi3(pdata) \ | ||
44 | dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata) | ||
45 | #define db5500_add_sdi4(pdata) \ | ||
46 | dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata) | ||
47 | |||
48 | #define db5500_add_spi0(pdata) \ | ||
49 | dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata) | ||
50 | #define db5500_add_spi1(pdata) \ | ||
51 | dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata) | ||
52 | #define db5500_add_spi2(pdata) \ | ||
53 | dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata) | ||
54 | #define db5500_add_spi3(pdata) \ | ||
55 | dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata) | ||
56 | |||
57 | #define db5500_add_uart0() \ | ||
58 | dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0) | ||
59 | #define db5500_add_uart1() \ | ||
60 | dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1) | ||
61 | #define db5500_add_uart2() \ | ||
62 | dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2) | ||
63 | #define db5500_add_uart3() \ | ||
64 | dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3) | ||
65 | |||
66 | #endif | ||
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 4a94be3304b9..23c695d54977 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c | |||
@@ -19,173 +19,6 @@ | |||
19 | 19 | ||
20 | #include "ste-dma40-db8500.h" | 20 | #include "ste-dma40-db8500.h" |
21 | 21 | ||
22 | static struct nmk_gpio_platform_data u8500_gpio_data[] = { | ||
23 | GPIO_DATA("GPIO-0-31", 0), | ||
24 | GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ | ||
25 | GPIO_DATA("GPIO-64-95", 64), | ||
26 | GPIO_DATA("GPIO-96-127", 96), /* 98..127 not routed to pin */ | ||
27 | GPIO_DATA("GPIO-128-159", 128), | ||
28 | GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */ | ||
29 | GPIO_DATA("GPIO-192-223", 192), | ||
30 | GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */ | ||
31 | GPIO_DATA("GPIO-256-288", 256), /* 268..288 not routed to pin */ | ||
32 | }; | ||
33 | |||
34 | static struct resource u8500_gpio_resources[] = { | ||
35 | GPIO_RESOURCE(0), | ||
36 | GPIO_RESOURCE(1), | ||
37 | GPIO_RESOURCE(2), | ||
38 | GPIO_RESOURCE(3), | ||
39 | GPIO_RESOURCE(4), | ||
40 | GPIO_RESOURCE(5), | ||
41 | GPIO_RESOURCE(6), | ||
42 | GPIO_RESOURCE(7), | ||
43 | GPIO_RESOURCE(8), | ||
44 | }; | ||
45 | |||
46 | struct platform_device u8500_gpio_devs[] = { | ||
47 | GPIO_DEVICE(0), | ||
48 | GPIO_DEVICE(1), | ||
49 | GPIO_DEVICE(2), | ||
50 | GPIO_DEVICE(3), | ||
51 | GPIO_DEVICE(4), | ||
52 | GPIO_DEVICE(5), | ||
53 | GPIO_DEVICE(6), | ||
54 | GPIO_DEVICE(7), | ||
55 | GPIO_DEVICE(8), | ||
56 | }; | ||
57 | |||
58 | struct amba_device u8500_ssp0_device = { | ||
59 | .dev = { | ||
60 | .coherent_dma_mask = ~0, | ||
61 | .init_name = "ssp0", | ||
62 | }, | ||
63 | .res = { | ||
64 | .start = U8500_SSP0_BASE, | ||
65 | .end = U8500_SSP0_BASE + SZ_4K - 1, | ||
66 | .flags = IORESOURCE_MEM, | ||
67 | }, | ||
68 | .irq = {IRQ_DB8500_SSP0, NO_IRQ }, | ||
69 | /* ST-Ericsson modified id */ | ||
70 | .periphid = SSP_PER_ID, | ||
71 | }; | ||
72 | |||
73 | static struct resource u8500_i2c0_resources[] = { | ||
74 | [0] = { | ||
75 | .start = U8500_I2C0_BASE, | ||
76 | .end = U8500_I2C0_BASE + SZ_4K - 1, | ||
77 | .flags = IORESOURCE_MEM, | ||
78 | }, | ||
79 | [1] = { | ||
80 | .start = IRQ_DB8500_I2C0, | ||
81 | .end = IRQ_DB8500_I2C0, | ||
82 | .flags = IORESOURCE_IRQ, | ||
83 | } | ||
84 | }; | ||
85 | |||
86 | struct platform_device u8500_i2c0_device = { | ||
87 | .name = "nmk-i2c", | ||
88 | .id = 0, | ||
89 | .resource = u8500_i2c0_resources, | ||
90 | .num_resources = ARRAY_SIZE(u8500_i2c0_resources), | ||
91 | }; | ||
92 | |||
93 | static struct resource u8500_i2c4_resources[] = { | ||
94 | [0] = { | ||
95 | .start = U8500_I2C4_BASE, | ||
96 | .end = U8500_I2C4_BASE + SZ_4K - 1, | ||
97 | .flags = IORESOURCE_MEM, | ||
98 | }, | ||
99 | [1] = { | ||
100 | .start = IRQ_DB8500_I2C4, | ||
101 | .end = IRQ_DB8500_I2C4, | ||
102 | .flags = IORESOURCE_IRQ, | ||
103 | } | ||
104 | }; | ||
105 | |||
106 | struct platform_device u8500_i2c4_device = { | ||
107 | .name = "nmk-i2c", | ||
108 | .id = 4, | ||
109 | .resource = u8500_i2c4_resources, | ||
110 | .num_resources = ARRAY_SIZE(u8500_i2c4_resources), | ||
111 | }; | ||
112 | |||
113 | /* | ||
114 | * SD/MMC | ||
115 | */ | ||
116 | |||
117 | struct amba_device u8500_sdi0_device = { | ||
118 | .dev = { | ||
119 | .init_name = "sdi0", | ||
120 | }, | ||
121 | .res = { | ||
122 | .start = U8500_SDI0_BASE, | ||
123 | .end = U8500_SDI0_BASE + SZ_4K - 1, | ||
124 | .flags = IORESOURCE_MEM, | ||
125 | }, | ||
126 | .irq = {IRQ_DB8500_SDMMC0, NO_IRQ}, | ||
127 | }; | ||
128 | |||
129 | struct amba_device u8500_sdi1_device = { | ||
130 | .dev = { | ||
131 | .init_name = "sdi1", | ||
132 | }, | ||
133 | .res = { | ||
134 | .start = U8500_SDI1_BASE, | ||
135 | .end = U8500_SDI1_BASE + SZ_4K - 1, | ||
136 | .flags = IORESOURCE_MEM, | ||
137 | }, | ||
138 | .irq = {IRQ_DB8500_SDMMC1, NO_IRQ}, | ||
139 | }; | ||
140 | |||
141 | struct amba_device u8500_sdi2_device = { | ||
142 | .dev = { | ||
143 | .init_name = "sdi2", | ||
144 | }, | ||
145 | .res = { | ||
146 | .start = U8500_SDI2_BASE, | ||
147 | .end = U8500_SDI2_BASE + SZ_4K - 1, | ||
148 | .flags = IORESOURCE_MEM, | ||
149 | }, | ||
150 | .irq = {IRQ_DB8500_SDMMC2, NO_IRQ}, | ||
151 | }; | ||
152 | |||
153 | struct amba_device u8500_sdi3_device = { | ||
154 | .dev = { | ||
155 | .init_name = "sdi3", | ||
156 | }, | ||
157 | .res = { | ||
158 | .start = U8500_SDI3_BASE, | ||
159 | .end = U8500_SDI3_BASE + SZ_4K - 1, | ||
160 | .flags = IORESOURCE_MEM, | ||
161 | }, | ||
162 | .irq = {IRQ_DB8500_SDMMC3, NO_IRQ}, | ||
163 | }; | ||
164 | |||
165 | struct amba_device u8500_sdi4_device = { | ||
166 | .dev = { | ||
167 | .init_name = "sdi4", | ||
168 | }, | ||
169 | .res = { | ||
170 | .start = U8500_SDI4_BASE, | ||
171 | .end = U8500_SDI4_BASE + SZ_4K - 1, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }, | ||
174 | .irq = {IRQ_DB8500_SDMMC4, NO_IRQ}, | ||
175 | }; | ||
176 | |||
177 | struct amba_device u8500_sdi5_device = { | ||
178 | .dev = { | ||
179 | .init_name = "sdi5", | ||
180 | }, | ||
181 | .res = { | ||
182 | .start = U8500_SDI5_BASE, | ||
183 | .end = U8500_SDI5_BASE + SZ_4K - 1, | ||
184 | .flags = IORESOURCE_MEM, | ||
185 | }, | ||
186 | .irq = {IRQ_DB8500_SDMMC5, NO_IRQ}, | ||
187 | }; | ||
188 | |||
189 | static struct resource dma40_resources[] = { | 22 | static struct resource dma40_resources[] = { |
190 | [0] = { | 23 | [0] = { |
191 | .start = U8500_DMA_BASE, | 24 | .start = U8500_DMA_BASE, |
@@ -295,7 +128,7 @@ struct resource keypad_resources[] = { | |||
295 | }, | 128 | }, |
296 | }; | 129 | }; |
297 | 130 | ||
298 | struct platform_device ux500_ske_keypad_device = { | 131 | struct platform_device u8500_ske_keypad_device = { |
299 | .name = "nmk-ske-keypad", | 132 | .name = "nmk-ske-keypad", |
300 | .id = -1, | 133 | .id = -1, |
301 | .num_resources = ARRAY_SIZE(keypad_resources), | 134 | .num_resources = ARRAY_SIZE(keypad_resources), |
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h new file mode 100644 index 000000000000..3a770c756979 --- /dev/null +++ b/arch/arm/mach-ux500/devices-db8500.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #ifndef __DEVICES_DB8500_H | ||
9 | #define __DEVICES_DB8500_H | ||
10 | |||
11 | #include "devices-common.h" | ||
12 | |||
13 | struct ske_keypad_platform_data; | ||
14 | struct pl022_ssp_controller; | ||
15 | |||
16 | static inline struct platform_device * | ||
17 | db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata) | ||
18 | { | ||
19 | return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1, | ||
20 | U8500_SKE_BASE, | ||
21 | IRQ_DB8500_KB, pdata); | ||
22 | } | ||
23 | |||
24 | static inline struct amba_device * | ||
25 | db8500_add_ssp(const char *name, resource_size_t base, int irq, | ||
26 | struct pl022_ssp_controller *pdata) | ||
27 | { | ||
28 | return dbx500_add_amba_device(name, base, irq, pdata, SSP_PER_ID); | ||
29 | } | ||
30 | |||
31 | |||
32 | #define db8500_add_i2c0(pdata) \ | ||
33 | dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) | ||
34 | #define db8500_add_i2c1(pdata) \ | ||
35 | dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) | ||
36 | #define db8500_add_i2c2(pdata) \ | ||
37 | dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) | ||
38 | #define db8500_add_i2c3(pdata) \ | ||
39 | dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) | ||
40 | #define db8500_add_i2c4(pdata) \ | ||
41 | dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) | ||
42 | |||
43 | #define db8500_add_msp0_i2s(pdata) \ | ||
44 | dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) | ||
45 | #define db8500_add_msp1_i2s(pdata) \ | ||
46 | dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) | ||
47 | #define db8500_add_msp2_i2s(pdata) \ | ||
48 | dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) | ||
49 | #define db8500_add_msp3_i2s(pdata) \ | ||
50 | dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) | ||
51 | |||
52 | #define db8500_add_msp0_spi(pdata) \ | ||
53 | dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) | ||
54 | #define db8500_add_msp1_spi(pdata) \ | ||
55 | dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) | ||
56 | #define db8500_add_msp2_spi(pdata) \ | ||
57 | dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) | ||
58 | #define db8500_add_msp3_spi(pdata) \ | ||
59 | dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) | ||
60 | |||
61 | #define db8500_add_rtc() \ | ||
62 | dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC); | ||
63 | |||
64 | #define db8500_add_sdi0(pdata) \ | ||
65 | dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata) | ||
66 | #define db8500_add_sdi1(pdata) \ | ||
67 | dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata) | ||
68 | #define db8500_add_sdi2(pdata) \ | ||
69 | dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata) | ||
70 | #define db8500_add_sdi3(pdata) \ | ||
71 | dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata) | ||
72 | #define db8500_add_sdi4(pdata) \ | ||
73 | dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata) | ||
74 | #define db8500_add_sdi5(pdata) \ | ||
75 | dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata) | ||
76 | |||
77 | #define db8500_add_ssp0(pdata) \ | ||
78 | db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata) | ||
79 | #define db8500_add_ssp1(pdata) \ | ||
80 | db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata) | ||
81 | |||
82 | #define db8500_add_spi0(pdata) \ | ||
83 | dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata) | ||
84 | #define db8500_add_spi1(pdata) \ | ||
85 | dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata) | ||
86 | #define db8500_add_spi2(pdata) \ | ||
87 | dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata) | ||
88 | #define db8500_add_spi3(pdata) \ | ||
89 | dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata) | ||
90 | |||
91 | #define db8500_add_uart0() \ | ||
92 | dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0) | ||
93 | #define db8500_add_uart1() \ | ||
94 | dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1) | ||
95 | #define db8500_add_uart2() \ | ||
96 | dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2) | ||
97 | |||
98 | #endif | ||
diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c index 8a268893cb7f..ea0a2f92ca70 100644 --- a/arch/arm/mach-ux500/devices.c +++ b/arch/arm/mach-ux500/devices.c | |||
@@ -14,69 +14,6 @@ | |||
14 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
15 | #include <mach/setup.h> | 15 | #include <mach/setup.h> |
16 | 16 | ||
17 | #define __MEM_4K_RESOURCE(x) \ | ||
18 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} | ||
19 | |||
20 | struct amba_device ux500_pl031_device = { | ||
21 | .dev = { | ||
22 | .init_name = "pl031", | ||
23 | }, | ||
24 | .res = { | ||
25 | .start = UX500_RTC_BASE, | ||
26 | .end = UX500_RTC_BASE + SZ_4K - 1, | ||
27 | .flags = IORESOURCE_MEM, | ||
28 | }, | ||
29 | .irq = {IRQ_RTC_RTT, NO_IRQ}, | ||
30 | }; | ||
31 | |||
32 | struct amba_device ux500_uart0_device = { | ||
33 | .dev = { .init_name = "uart0" }, | ||
34 | __MEM_4K_RESOURCE(UX500_UART0_BASE), | ||
35 | .irq = {IRQ_UART0, NO_IRQ}, | ||
36 | }; | ||
37 | |||
38 | struct amba_device ux500_uart1_device = { | ||
39 | .dev = { .init_name = "uart1" }, | ||
40 | __MEM_4K_RESOURCE(UX500_UART1_BASE), | ||
41 | .irq = {IRQ_UART1, NO_IRQ}, | ||
42 | }; | ||
43 | |||
44 | struct amba_device ux500_uart2_device = { | ||
45 | .dev = { .init_name = "uart2" }, | ||
46 | __MEM_4K_RESOURCE(UX500_UART2_BASE), | ||
47 | .irq = {IRQ_UART2, NO_IRQ}, | ||
48 | }; | ||
49 | |||
50 | #define UX500_I2C_RESOURCES(id, size) \ | ||
51 | static struct resource ux500_i2c##id##_resources[] = { \ | ||
52 | [0] = { \ | ||
53 | .start = UX500_I2C##id##_BASE, \ | ||
54 | .end = UX500_I2C##id##_BASE + size - 1, \ | ||
55 | .flags = IORESOURCE_MEM, \ | ||
56 | }, \ | ||
57 | [1] = { \ | ||
58 | .start = IRQ_I2C##id, \ | ||
59 | .end = IRQ_I2C##id, \ | ||
60 | .flags = IORESOURCE_IRQ \ | ||
61 | } \ | ||
62 | } | ||
63 | |||
64 | UX500_I2C_RESOURCES(1, SZ_4K); | ||
65 | UX500_I2C_RESOURCES(2, SZ_4K); | ||
66 | UX500_I2C_RESOURCES(3, SZ_4K); | ||
67 | |||
68 | #define UX500_I2C_PDEVICE(cid) \ | ||
69 | struct platform_device ux500_i2c##cid##_device = { \ | ||
70 | .name = "nmk-i2c", \ | ||
71 | .id = cid, \ | ||
72 | .num_resources = 2, \ | ||
73 | .resource = ux500_i2c##cid##_resources, \ | ||
74 | } | ||
75 | |||
76 | UX500_I2C_PDEVICE(1); | ||
77 | UX500_I2C_PDEVICE(2); | ||
78 | UX500_I2C_PDEVICE(3); | ||
79 | |||
80 | void __init amba_add_devices(struct amba_device *devs[], int num) | 17 | void __init amba_add_devices(struct amba_device *devs[], int num) |
81 | { | 18 | { |
82 | int i; | 19 | int i; |
diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c new file mode 100644 index 000000000000..32a061f8a95b --- /dev/null +++ b/arch/arm/mach-ux500/dma-db5500.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson | ||
5 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson | ||
6 | * Author: Rabin Vincent <rabinv.vincent@stericsson.com> for ST-Ericsson | ||
7 | * | ||
8 | * License terms: GNU General Public License (GPL), version 2 | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | |||
14 | #include <plat/ste_dma40.h> | ||
15 | #include <mach/setup.h> | ||
16 | #include <mach/hardware.h> | ||
17 | |||
18 | #include "ste-dma40-db5500.h" | ||
19 | |||
20 | static struct resource dma40_resources[] = { | ||
21 | [0] = { | ||
22 | .start = U5500_DMA_BASE, | ||
23 | .end = U5500_DMA_BASE + SZ_4K - 1, | ||
24 | .flags = IORESOURCE_MEM, | ||
25 | .name = "base", | ||
26 | }, | ||
27 | [1] = { | ||
28 | .start = U5500_DMA_LCPA_BASE, | ||
29 | .end = U5500_DMA_LCPA_BASE + 2 * SZ_1K - 1, | ||
30 | .flags = IORESOURCE_MEM, | ||
31 | .name = "lcpa", | ||
32 | }, | ||
33 | [2] = { | ||
34 | .start = IRQ_DB5500_DMA, | ||
35 | .end = IRQ_DB5500_DMA, | ||
36 | .flags = IORESOURCE_IRQ | ||
37 | } | ||
38 | }; | ||
39 | |||
40 | /* Default configuration for physical memcpy */ | ||
41 | static struct stedma40_chan_cfg dma40_memcpy_conf_phy = { | ||
42 | .mode = STEDMA40_MODE_PHYSICAL, | ||
43 | .dir = STEDMA40_MEM_TO_MEM, | ||
44 | |||
45 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
46 | .src_info.psize = STEDMA40_PSIZE_PHY_1, | ||
47 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
48 | |||
49 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
50 | .dst_info.psize = STEDMA40_PSIZE_PHY_1, | ||
51 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
52 | }; | ||
53 | |||
54 | /* Default configuration for logical memcpy */ | ||
55 | static struct stedma40_chan_cfg dma40_memcpy_conf_log = { | ||
56 | .dir = STEDMA40_MEM_TO_MEM, | ||
57 | |||
58 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
59 | .src_info.psize = STEDMA40_PSIZE_LOG_1, | ||
60 | .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
61 | |||
62 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
63 | .dst_info.psize = STEDMA40_PSIZE_LOG_1, | ||
64 | .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL, | ||
65 | }; | ||
66 | |||
67 | /* | ||
68 | * Mapping between soruce event lines and physical device address This was | ||
69 | * created assuming that the event line is tied to a device and therefore the | ||
70 | * address is constant, however this is not true for at least USB, and the | ||
71 | * values are just placeholders for USB. This table is preserved and used for | ||
72 | * now. | ||
73 | */ | ||
74 | static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = { | ||
75 | [DB5500_DMA_DEV24_SDMMC0_RX] = -1, | ||
76 | }; | ||
77 | |||
78 | /* Mapping between destination event lines and physical device address */ | ||
79 | static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = { | ||
80 | [DB5500_DMA_DEV24_SDMMC0_TX] = -1, | ||
81 | }; | ||
82 | |||
83 | static int dma40_memcpy_event[] = { | ||
84 | DB5500_DMA_MEMCPY_TX_1, | ||
85 | DB5500_DMA_MEMCPY_TX_2, | ||
86 | DB5500_DMA_MEMCPY_TX_3, | ||
87 | DB5500_DMA_MEMCPY_TX_4, | ||
88 | DB5500_DMA_MEMCPY_TX_5, | ||
89 | }; | ||
90 | |||
91 | static struct stedma40_platform_data dma40_plat_data = { | ||
92 | .dev_len = ARRAY_SIZE(dma40_rx_map), | ||
93 | .dev_rx = dma40_rx_map, | ||
94 | .dev_tx = dma40_tx_map, | ||
95 | .memcpy = dma40_memcpy_event, | ||
96 | .memcpy_len = ARRAY_SIZE(dma40_memcpy_event), | ||
97 | .memcpy_conf_phy = &dma40_memcpy_conf_phy, | ||
98 | .memcpy_conf_log = &dma40_memcpy_conf_log, | ||
99 | .disabled_channels = {-1}, | ||
100 | }; | ||
101 | |||
102 | static struct platform_device dma40_device = { | ||
103 | .dev = { | ||
104 | .platform_data = &dma40_plat_data, | ||
105 | }, | ||
106 | .name = "dma40", | ||
107 | .id = 0, | ||
108 | .num_resources = ARRAY_SIZE(dma40_resources), | ||
109 | .resource = dma40_resources | ||
110 | }; | ||
111 | |||
112 | void __init db5500_dma_init(void) | ||
113 | { | ||
114 | int ret; | ||
115 | |||
116 | ret = platform_device_register(&dma40_device); | ||
117 | if (ret) | ||
118 | dev_err(&dma40_device.dev, "unable to register device: %d\n", ret); | ||
119 | |||
120 | } | ||
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h index 3eafc0e24ba5..bd88c1e74060 100644 --- a/arch/arm/mach-ux500/include/mach/db5500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h | |||
@@ -114,4 +114,8 @@ | |||
114 | #define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20) | 114 | #define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20) |
115 | #define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F) | 115 | #define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F) |
116 | 116 | ||
117 | #define U5500_ESRAM_BASE 0x40000000 | ||
118 | #define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000 | ||
119 | #define U5500_DMA_LCPA_BASE (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET) | ||
120 | |||
117 | #endif | 121 | #endif |
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index f07d0986409d..0fefb34c11e4 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h | |||
@@ -92,7 +92,8 @@ | |||
92 | #define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) | 92 | #define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) |
93 | #define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) | 93 | #define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) |
94 | #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) | 94 | #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) |
95 | #define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x0f000) | 95 | #define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000) |
96 | #define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) | ||
96 | 97 | ||
97 | /* per3 base addresses */ | 98 | /* per3 base addresses */ |
98 | #define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) | 99 | #define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) |
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index b91a4d1211a2..020b6369a30a 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h | |||
@@ -14,27 +14,10 @@ extern struct platform_device u5500_gpio_devs[]; | |||
14 | extern struct platform_device u8500_gpio_devs[]; | 14 | extern struct platform_device u8500_gpio_devs[]; |
15 | 15 | ||
16 | extern struct amba_device ux500_pl031_device; | 16 | extern struct amba_device ux500_pl031_device; |
17 | extern struct amba_device u8500_ssp0_device; | ||
18 | extern struct amba_device ux500_uart0_device; | ||
19 | extern struct amba_device ux500_uart1_device; | ||
20 | extern struct amba_device ux500_uart2_device; | ||
21 | 17 | ||
22 | extern struct platform_device ux500_i2c1_device; | ||
23 | extern struct platform_device ux500_i2c2_device; | ||
24 | extern struct platform_device ux500_i2c3_device; | ||
25 | |||
26 | extern struct platform_device u8500_i2c0_device; | ||
27 | extern struct platform_device u8500_i2c4_device; | ||
28 | extern struct platform_device u8500_dma40_device; | 18 | extern struct platform_device u8500_dma40_device; |
29 | extern struct platform_device ux500_ske_keypad_device; | 19 | extern struct platform_device ux500_ske_keypad_device; |
30 | 20 | ||
31 | extern struct amba_device u8500_sdi0_device; | ||
32 | extern struct amba_device u8500_sdi1_device; | ||
33 | extern struct amba_device u8500_sdi2_device; | ||
34 | extern struct amba_device u8500_sdi3_device; | ||
35 | extern struct amba_device u8500_sdi4_device; | ||
36 | extern struct amba_device u8500_sdi5_device; | ||
37 | |||
38 | void dma40_u8500ed_fixup(void); | 21 | void dma40_u8500ed_fixup(void); |
39 | 22 | ||
40 | #endif | 23 | #endif |
diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h index d548a622e7d2..3c4cd31ad9f7 100644 --- a/arch/arm/mach-ux500/include/mach/gpio.h +++ b/arch/arm/mach-ux500/include/mach/gpio.h | |||
@@ -9,42 +9,4 @@ | |||
9 | 9 | ||
10 | #include <plat/gpio.h> | 10 | #include <plat/gpio.h> |
11 | 11 | ||
12 | #define __GPIO_RESOURCE(soc, block) \ | ||
13 | { \ | ||
14 | .start = soc##_GPIOBANK##block##_BASE, \ | ||
15 | .end = soc##_GPIOBANK##block##_BASE + 127, \ | ||
16 | .flags = IORESOURCE_MEM, \ | ||
17 | }, \ | ||
18 | { \ | ||
19 | .start = IRQ_GPIO##block, \ | ||
20 | .end = IRQ_GPIO##block, \ | ||
21 | .flags = IORESOURCE_IRQ, \ | ||
22 | } | ||
23 | |||
24 | #define __GPIO_DEVICE(soc, block) \ | ||
25 | { \ | ||
26 | .name = "gpio", \ | ||
27 | .id = block, \ | ||
28 | .num_resources = 2, \ | ||
29 | .resource = &soc##_gpio_resources[block * 2], \ | ||
30 | .dev = { \ | ||
31 | .platform_data = &soc##_gpio_data[block], \ | ||
32 | }, \ | ||
33 | } | ||
34 | |||
35 | #define GPIO_DATA(_name, first) \ | ||
36 | { \ | ||
37 | .name = _name, \ | ||
38 | .first_gpio = first, \ | ||
39 | .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ | ||
40 | } | ||
41 | |||
42 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
43 | #define GPIO_RESOURCE(block) __GPIO_RESOURCE(U8500, block) | ||
44 | #define GPIO_DEVICE(block) __GPIO_DEVICE(u8500, block) | ||
45 | #elif defined(CONFIG_UX500_SOC_DB5500) | ||
46 | #define GPIO_RESOURCE(block) __GPIO_RESOURCE(U5500, block) | ||
47 | #define GPIO_DEVICE(block) __GPIO_DEVICE(u5500, block) | ||
48 | #endif | ||
49 | |||
50 | #endif /* __ASM_ARCH_GPIO_H */ | 12 | #endif /* __ASM_ARCH_GPIO_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 32e883a8f2a2..6295cc581355 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h | |||
@@ -142,6 +142,8 @@ static inline bool cpu_is_u5500(void) | |||
142 | #endif | 142 | #endif |
143 | } | 143 | } |
144 | 144 | ||
145 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) | ||
146 | |||
145 | #endif | 147 | #endif |
146 | 148 | ||
147 | #endif /* __MACH_HARDWARE_H */ | 149 | #endif /* __MACH_HARDWARE_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h index cca4f705601e..7cdeb2af0ebb 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h | |||
@@ -8,12 +8,36 @@ | |||
8 | #ifndef __MACH_IRQS_BOARD_MOP500_H | 8 | #ifndef __MACH_IRQS_BOARD_MOP500_H |
9 | #define __MACH_IRQS_BOARD_MOP500_H | 9 | #define __MACH_IRQS_BOARD_MOP500_H |
10 | 10 | ||
11 | #define AB8500_NR_IRQS 104 | 11 | /* Number of AB8500 irqs is taken from header file */ |
12 | #include <linux/mfd/ab8500.h> | ||
12 | 13 | ||
13 | #define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START | 14 | #define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START |
14 | #define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \ | 15 | #define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \ |
15 | + AB8500_NR_IRQS) | 16 | + AB8500_NR_IRQS) |
16 | #define MOP500_IRQ_END MOP500_AB8500_IRQ_END | 17 | |
18 | /* TC35892 */ | ||
19 | #define TC35892_NR_INTERNAL_IRQS 8 | ||
20 | #define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x)) | ||
21 | #define TC35892_NR_GPIOS 24 | ||
22 | #define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS) | ||
23 | |||
24 | #define MOP500_EGPIO_NR_IRQS TC35892_NR_IRQS | ||
25 | |||
26 | #define MOP500_EGPIO_IRQ_BASE MOP500_AB8500_IRQ_END | ||
27 | #define MOP500_EGPIO_IRQ_END (MOP500_EGPIO_IRQ_BASE \ | ||
28 | + MOP500_EGPIO_NR_IRQS) | ||
29 | /* STMPE1601 irqs */ | ||
30 | #define STMPE_NR_INTERNAL_IRQS 9 | ||
31 | #define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x)) | ||
32 | #define STMPE_NR_GPIOS 24 | ||
33 | #define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS) | ||
34 | |||
35 | #define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END | ||
36 | #define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x)) | ||
37 | |||
38 | #define MOP500_NR_IRQS MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS) | ||
39 | |||
40 | #define MOP500_IRQ_END MOP500_NR_IRQS | ||
17 | 41 | ||
18 | #if MOP500_IRQ_END > IRQ_BOARD_END | 42 | #if MOP500_IRQ_END > IRQ_BOARD_END |
19 | #undef IRQ_BOARD_END | 43 | #undef IRQ_BOARD_END |
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 693aa57de88d..880ae45bc235 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h | |||
@@ -21,50 +21,6 @@ | |||
21 | 21 | ||
22 | /* Interrupt numbers generic for shared peripheral */ | 22 | /* Interrupt numbers generic for shared peripheral */ |
23 | #define IRQ_MTU0 (IRQ_SHPI_START + 4) | 23 | #define IRQ_MTU0 (IRQ_SHPI_START + 4) |
24 | #define IRQ_SPI2 (IRQ_SHPI_START + 6) | ||
25 | #define IRQ_SPI0 (IRQ_SHPI_START + 8) | ||
26 | #define IRQ_UART0 (IRQ_SHPI_START + 11) | ||
27 | #define IRQ_I2C3 (IRQ_SHPI_START + 12) | ||
28 | #define IRQ_SSP0 (IRQ_SHPI_START + 14) | ||
29 | #define IRQ_MTU1 (IRQ_SHPI_START + 17) | ||
30 | #define IRQ_RTC_RTT (IRQ_SHPI_START + 18) | ||
31 | #define IRQ_UART1 (IRQ_SHPI_START + 19) | ||
32 | #define IRQ_I2C0 (IRQ_SHPI_START + 21) | ||
33 | #define IRQ_I2C1 (IRQ_SHPI_START + 22) | ||
34 | #define IRQ_USBOTG (IRQ_SHPI_START + 23) | ||
35 | #define IRQ_DMA (IRQ_SHPI_START + 25) | ||
36 | #define IRQ_UART2 (IRQ_SHPI_START + 26) | ||
37 | #define IRQ_HSIR_EXCEP (IRQ_SHPI_START + 29) | ||
38 | #define IRQ_MSP0 (IRQ_SHPI_START + 31) | ||
39 | #define IRQ_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32) | ||
40 | #define IRQ_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33) | ||
41 | #define IRQ_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34) | ||
42 | #define IRQ_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35) | ||
43 | #define IRQ_AB8500 (IRQ_SHPI_START + 40) | ||
44 | #define IRQ_PRCMU (IRQ_SHPI_START + 47) | ||
45 | #define IRQ_DISP (IRQ_SHPI_START + 48) | ||
46 | #define IRQ_SiPI3 (IRQ_SHPI_START + 49) | ||
47 | #define IRQ_I2C4 (IRQ_SHPI_START + 51) | ||
48 | #define IRQ_SSP1 (IRQ_SHPI_START + 52) | ||
49 | #define IRQ_I2C2 (IRQ_SHPI_START + 55) | ||
50 | #define IRQ_SDMMC0 (IRQ_SHPI_START + 60) | ||
51 | #define IRQ_MSP1 (IRQ_SHPI_START + 62) | ||
52 | #define IRQ_SPI1 (IRQ_SHPI_START + 96) | ||
53 | #define IRQ_MSP2 (IRQ_SHPI_START + 98) | ||
54 | #define IRQ_SDMMC4 (IRQ_SHPI_START + 99) | ||
55 | #define IRQ_HSIRD0 (IRQ_SHPI_START + 104) | ||
56 | #define IRQ_HSIRD1 (IRQ_SHPI_START + 105) | ||
57 | #define IRQ_HSITD0 (IRQ_SHPI_START + 106) | ||
58 | #define IRQ_HSITD1 (IRQ_SHPI_START + 107) | ||
59 | #define IRQ_GPIO0 (IRQ_SHPI_START + 119) | ||
60 | #define IRQ_GPIO1 (IRQ_SHPI_START + 120) | ||
61 | #define IRQ_GPIO2 (IRQ_SHPI_START + 121) | ||
62 | #define IRQ_GPIO3 (IRQ_SHPI_START + 122) | ||
63 | #define IRQ_GPIO4 (IRQ_SHPI_START + 123) | ||
64 | #define IRQ_GPIO5 (IRQ_SHPI_START + 124) | ||
65 | #define IRQ_GPIO6 (IRQ_SHPI_START + 125) | ||
66 | #define IRQ_GPIO7 (IRQ_SHPI_START + 126) | ||
67 | #define IRQ_GPIO8 (IRQ_SHPI_START + 127) | ||
68 | 24 | ||
69 | /* There are 128 shared peripheral interrupts assigned to | 25 | /* There are 128 shared peripheral interrupts assigned to |
70 | * INTID[160:32]. The first 32 interrupts are reserved. | 26 | * INTID[160:32]. The first 32 interrupts are reserved. |
diff --git a/arch/arm/mach-ux500/include/mach/mbox.h b/arch/arm/mach-ux500/include/mach/mbox-db5500.h index 7f9da4d2fbda..7f9da4d2fbda 100644 --- a/arch/arm/mach-ux500/include/mach/mbox.h +++ b/arch/arm/mach-ux500/include/mach/mbox-db5500.h | |||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-defs.h b/arch/arm/mach-ux500/include/mach/prcmu-defs.h new file mode 100644 index 000000000000..848ba64b561f --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/prcmu-defs.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
6 | * Author: Martin Persson <martin.persson@stericsson.com> | ||
7 | * | ||
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * PRCM Unit definitions | ||
11 | */ | ||
12 | |||
13 | #ifndef __MACH_PRCMU_DEFS_H | ||
14 | #define __MACH_PRCMU_DEFS_H | ||
15 | |||
16 | enum prcmu_cpu_opp { | ||
17 | CPU_OPP_INIT = 0x00, | ||
18 | CPU_OPP_NO_CHANGE = 0x01, | ||
19 | CPU_OPP_100 = 0x02, | ||
20 | CPU_OPP_50 = 0x03, | ||
21 | CPU_OPP_MAX = 0x04, | ||
22 | CPU_OPP_EXT_CLK = 0x07 | ||
23 | }; | ||
24 | enum prcmu_ape_opp { | ||
25 | APE_OPP_NO_CHANGE = 0x00, | ||
26 | APE_OPP_100 = 0x02, | ||
27 | APE_OPP_50 = 0x03, | ||
28 | }; | ||
29 | |||
30 | #endif /* __MACH_PRCMU_DEFS_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h index 8885f39a6421..455467e88791 100644 --- a/arch/arm/mach-ux500/include/mach/prcmu-regs.h +++ b/arch/arm/mach-ux500/include/mach/prcmu-regs.h | |||
@@ -1,10 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2009 ST-Ericsson SA | 2 | * Copyright (C) STMicroelectronics 2009 |
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify | 5 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> |
5 | * it under the terms of the GNU General Public License version 2 | 6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> |
6 | * as published by the Free Software Foundation. | 7 | * |
8 | * License Terms: GNU General Public License v2 | ||
9 | * | ||
10 | * PRCM Unit registers | ||
7 | */ | 11 | */ |
12 | |||
8 | #ifndef __MACH_PRCMU_REGS_H | 13 | #ifndef __MACH_PRCMU_REGS_H |
9 | #define __MACH_PRCMU_REGS_H | 14 | #define __MACH_PRCMU_REGS_H |
10 | 15 | ||
@@ -88,4 +93,4 @@ | |||
88 | /* Miscellaneous unit registers */ | 93 | /* Miscellaneous unit registers */ |
89 | #define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) | 94 | #define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) |
90 | 95 | ||
91 | #endif /* __MACH_PRCMU__REGS_H */ | 96 | #endif /* __MACH_PRCMU_REGS_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/prcmu.h b/arch/arm/mach-ux500/include/mach/prcmu.h index 549843ff6dbe..c49e456162ef 100644 --- a/arch/arm/mach-ux500/include/mach/prcmu.h +++ b/arch/arm/mach-ux500/include/mach/prcmu.h | |||
@@ -2,14 +2,27 @@ | |||
2 | * Copyright (C) STMicroelectronics 2009 | 2 | * Copyright (C) STMicroelectronics 2009 |
3 | * Copyright (C) ST-Ericsson SA 2010 | 3 | * Copyright (C) ST-Ericsson SA 2010 |
4 | * | 4 | * |
5 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
7 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
8 | * | ||
5 | * License Terms: GNU General Public License v2 | 9 | * License Terms: GNU General Public License v2 |
6 | * | 10 | * |
7 | * PRCMU f/w APIs | 11 | * PRCM Unit f/w API |
8 | */ | 12 | */ |
9 | #ifndef __MACH_PRCMU_H | 13 | #ifndef __MACH_PRCMU_H |
10 | #define __MACH_PRCMU_H | 14 | #define __MACH_PRCMU_H |
15 | #include <mach/prcmu-defs.h> | ||
11 | 16 | ||
17 | void __init prcmu_early_init(void); | ||
12 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | 18 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); |
13 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | 19 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); |
20 | int prcmu_set_ape_opp(enum prcmu_ape_opp opp); | ||
21 | int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp); | ||
22 | int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, | ||
23 | enum prcmu_cpu_opp cpu_opp); | ||
24 | int prcmu_get_ape_opp(void); | ||
25 | int prcmu_get_cpu_opp(void); | ||
26 | bool prcmu_has_arm_maxopp(void); | ||
14 | 27 | ||
15 | #endif /* __MACH_PRCMU_H */ | 28 | #endif /* __MACH_PRCMU_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 54bbe648bf58..469877e0de90 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
@@ -18,14 +18,19 @@ extern void __init ux500_map_io(void); | |||
18 | extern void __init u5500_map_io(void); | 18 | extern void __init u5500_map_io(void); |
19 | extern void __init u8500_map_io(void); | 19 | extern void __init u8500_map_io(void); |
20 | 20 | ||
21 | extern void __init ux500_init_devices(void); | ||
22 | extern void __init u5500_init_devices(void); | 21 | extern void __init u5500_init_devices(void); |
23 | extern void __init u8500_init_devices(void); | 22 | extern void __init u8500_init_devices(void); |
24 | 23 | ||
25 | extern void __init ux500_init_irq(void); | 24 | extern void __init ux500_init_irq(void); |
25 | |||
26 | extern void __init u5500_sdi_init(void); | ||
27 | |||
28 | extern void __init db5500_dma_init(void); | ||
29 | |||
26 | /* We re-use nomadik_timer for this platform */ | 30 | /* We re-use nomadik_timer for this platform */ |
27 | extern void nmdk_timer_init(void); | 31 | extern void nmdk_timer_init(void); |
28 | 32 | ||
33 | struct amba_device; | ||
29 | extern void __init amba_add_devices(struct amba_device *devs[], int num); | 34 | extern void __init amba_add_devices(struct amba_device *devs[], int num); |
30 | 35 | ||
31 | struct sys_timer; | 36 | struct sys_timer; |
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h index 0271ca0a83df..9a6614c6808e 100644 --- a/arch/arm/mach-ux500/include/mach/uncompress.h +++ b/arch/arm/mach-ux500/include/mach/uncompress.h | |||
@@ -19,38 +19,43 @@ | |||
19 | #define __ASM_ARCH_UNCOMPRESS_H | 19 | #define __ASM_ARCH_UNCOMPRESS_H |
20 | 20 | ||
21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
22 | #include <asm/mach-types.h> | ||
22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/amba/serial.h> | ||
23 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
24 | 26 | ||
25 | #define U8500_UART_DR 0x80007000 | 27 | static u32 ux500_uart_base; |
26 | #define U8500_UART_LCRH 0x8000702c | ||
27 | #define U8500_UART_CR 0x80007030 | ||
28 | #define U8500_UART_FR 0x80007018 | ||
29 | 28 | ||
30 | static void putc(const char c) | 29 | static void putc(const char c) |
31 | { | 30 | { |
32 | /* Do nothing if the UART is not enabled. */ | 31 | /* Do nothing if the UART is not enabled. */ |
33 | if (!(__raw_readb(U8500_UART_CR) & 0x1)) | 32 | if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1)) |
34 | return; | 33 | return; |
35 | 34 | ||
36 | if (c == '\n') | 35 | if (c == '\n') |
37 | putc('\r'); | 36 | putc('\r'); |
38 | 37 | ||
39 | while (__raw_readb(U8500_UART_FR) & (1 << 5)) | 38 | while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 5)) |
40 | barrier(); | 39 | barrier(); |
41 | __raw_writeb(c, U8500_UART_DR); | 40 | __raw_writeb(c, ux500_uart_base + UART01x_DR); |
42 | } | 41 | } |
43 | 42 | ||
44 | static void flush(void) | 43 | static void flush(void) |
45 | { | 44 | { |
46 | if (!(__raw_readb(U8500_UART_CR) & 0x1)) | 45 | if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1)) |
47 | return; | 46 | return; |
48 | while (__raw_readb(U8500_UART_FR) & (1 << 3)) | 47 | while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 3)) |
49 | barrier(); | 48 | barrier(); |
50 | } | 49 | } |
51 | 50 | ||
52 | static inline void arch_decomp_setup(void) | 51 | static inline void arch_decomp_setup(void) |
53 | { | 52 | { |
53 | if (machine_is_u8500()) | ||
54 | ux500_uart_base = U8500_UART2_BASE; | ||
55 | else if (machine_is_u5500()) | ||
56 | ux500_uart_base = U5500_UART0_BASE; | ||
57 | else /* not much can be done to help here */ | ||
58 | ux500_uart_base = U8500_UART2_BASE; | ||
54 | } | 59 | } |
55 | 60 | ||
56 | #define arch_decomp_wdog() /* nothing to do here */ | 61 | #define arch_decomp_wdog() /* nothing to do here */ |
diff --git a/arch/arm/mach-ux500/mbox.c b/arch/arm/mach-ux500/mbox-db5500.c index 63435389c544..cbf15718fc3c 100644 --- a/arch/arm/mach-ux500/mbox.c +++ b/arch/arm/mach-ux500/mbox-db5500.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/debugfs.h> | 38 | #include <linux/debugfs.h> |
39 | #include <linux/seq_file.h> | 39 | #include <linux/seq_file.h> |
40 | #include <linux/completion.h> | 40 | #include <linux/completion.h> |
41 | #include <mach/mbox.h> | 41 | #include <mach/mbox-db5500.h> |
42 | 42 | ||
43 | #define MBOX_NAME "mbox" | 43 | #define MBOX_NAME "mbox" |
44 | 44 | ||
diff --git a/arch/arm/mach-ux500/modem_irq.c b/arch/arm/mach-ux500/modem-irq-db5500.c index 3187f8871169..3187f8871169 100644 --- a/arch/arm/mach-ux500/modem_irq.c +++ b/arch/arm/mach-ux500/modem-irq-db5500.c | |||
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 9e4c678de785..ade2e17f253c 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * control for which core is the next to come out of the secondary | 26 | * control for which core is the next to come out of the secondary |
27 | * boot "holding pen" | 27 | * boot "holding pen" |
28 | */ | 28 | */ |
29 | volatile int __cpuinitdata pen_release = -1; | 29 | volatile int pen_release = -1; |
30 | 30 | ||
31 | static unsigned int __init get_core_count(void) | 31 | static unsigned int __init get_core_count(void) |
32 | { | 32 | { |
diff --git a/arch/arm/mach-ux500/prcmu.c b/arch/arm/mach-ux500/prcmu.c index 293274d1342a..c522d26ef348 100644 --- a/arch/arm/mach-ux500/prcmu.c +++ b/arch/arm/mach-ux500/prcmu.c | |||
@@ -1,10 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) ST Ericsson SA 2010 | 2 | * Copyright (C) STMicroelectronics 2009 |
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | 4 | * |
4 | * License Terms: GNU General Public License v2 | 5 | * License Terms: GNU General Public License v2 |
6 | * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> | ||
7 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
5 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | 8 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> |
6 | * | 9 | * |
7 | * U8500 PRCMU driver. | 10 | * U8500 PRCM Unit interface driver |
11 | * | ||
8 | */ | 12 | */ |
9 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -19,11 +23,26 @@ | |||
19 | 23 | ||
20 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
21 | #include <mach/prcmu-regs.h> | 25 | #include <mach/prcmu-regs.h> |
26 | #include <mach/prcmu-defs.h> | ||
27 | |||
28 | /* Global var to runtime determine TCDM base for v2 or v1 */ | ||
29 | static __iomem void *tcdm_base; | ||
30 | |||
31 | #define _MBOX_HEADER (tcdm_base + 0xFE8) | ||
32 | #define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0) | ||
33 | |||
34 | #define REQ_MB1 (tcdm_base + 0xFD0) | ||
35 | #define REQ_MB5 (tcdm_base + 0xE44) | ||
22 | 36 | ||
23 | #define PRCMU_TCDM_BASE __io_address(U8500_PRCMU_TCDM_BASE) | 37 | #define REQ_MB1_ARMOPP (REQ_MB1 + 0x0) |
38 | #define REQ_MB1_APEOPP (REQ_MB1 + 0x1) | ||
39 | #define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2) | ||
24 | 40 | ||
25 | #define REQ_MB5 (PRCMU_TCDM_BASE + 0xE44) | 41 | #define ACK_MB1 (tcdm_base + 0xE04) |
26 | #define ACK_MB5 (PRCMU_TCDM_BASE + 0xDF4) | 42 | #define ACK_MB5 (tcdm_base + 0xDF4) |
43 | |||
44 | #define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0) | ||
45 | #define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1) | ||
27 | 46 | ||
28 | #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) | 47 | #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) |
29 | #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) | 48 | #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) |
@@ -33,10 +52,33 @@ | |||
33 | #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) | 52 | #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) |
34 | #define ACK_MB5_I2C_VAL (ACK_MB5 + 3) | 53 | #define ACK_MB5_I2C_VAL (ACK_MB5 + 3) |
35 | 54 | ||
36 | #define I2C_WRITE(slave) ((slave) << 1) | 55 | #define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4) |
37 | #define I2C_READ(slave) (((slave) << 1) | BIT(0)) | 56 | #define PRCM_AVS_ISMODEENABLE 7 |
57 | #define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) | ||
58 | |||
59 | #define I2C_WRITE(slave) \ | ||
60 | (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) | ||
61 | #define I2C_READ(slave) \ | ||
62 | (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0)) | ||
38 | #define I2C_STOP_EN BIT(3) | 63 | #define I2C_STOP_EN BIT(3) |
39 | 64 | ||
65 | enum mb1_h { | ||
66 | MB1H_ARM_OPP = 1, | ||
67 | MB1H_APE_OPP, | ||
68 | MB1H_ARM_APE_OPP, | ||
69 | }; | ||
70 | |||
71 | static struct { | ||
72 | struct mutex lock; | ||
73 | struct completion work; | ||
74 | struct { | ||
75 | u8 arm_opp; | ||
76 | u8 ape_opp; | ||
77 | u8 arm_status; | ||
78 | u8 ape_status; | ||
79 | } ack; | ||
80 | } mb1_transfer; | ||
81 | |||
40 | enum ack_mb5_status { | 82 | enum ack_mb5_status { |
41 | I2C_WR_OK = 0x01, | 83 | I2C_WR_OK = 0x01, |
42 | I2C_RD_OK = 0x02, | 84 | I2C_RD_OK = 0x02, |
@@ -145,6 +187,104 @@ unlock_and_return: | |||
145 | } | 187 | } |
146 | EXPORT_SYMBOL(prcmu_abb_write); | 188 | EXPORT_SYMBOL(prcmu_abb_write); |
147 | 189 | ||
190 | static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp, | ||
191 | enum prcmu_cpu_opp cpu_opp) | ||
192 | { | ||
193 | bool do_ape; | ||
194 | bool do_arm; | ||
195 | int err = 0; | ||
196 | |||
197 | do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP)); | ||
198 | do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP)); | ||
199 | |||
200 | mutex_lock(&mb1_transfer.lock); | ||
201 | |||
202 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) | ||
203 | cpu_relax(); | ||
204 | |||
205 | writeb(0, MBOX_HEADER_REQ_MB0); | ||
206 | writeb(cpu_opp, REQ_MB1_ARMOPP); | ||
207 | writeb(ape_opp, REQ_MB1_APEOPP); | ||
208 | writeb(0, REQ_MB1_BOOSTOPP); | ||
209 | writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); | ||
210 | wait_for_completion(&mb1_transfer.work); | ||
211 | if ((do_ape) && (mb1_transfer.ack.ape_status != 0)) | ||
212 | err = -EIO; | ||
213 | if ((do_arm) && (mb1_transfer.ack.arm_status != 0)) | ||
214 | err = -EIO; | ||
215 | |||
216 | mutex_unlock(&mb1_transfer.lock); | ||
217 | |||
218 | return err; | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * prcmu_set_ape_opp() - Set the OPP of the APE. | ||
223 | * @opp: The OPP to set. | ||
224 | * | ||
225 | * This function sets the OPP of the APE. | ||
226 | */ | ||
227 | int prcmu_set_ape_opp(enum prcmu_ape_opp opp) | ||
228 | { | ||
229 | return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE); | ||
230 | } | ||
231 | EXPORT_SYMBOL(prcmu_set_ape_opp); | ||
232 | |||
233 | /** | ||
234 | * prcmu_set_cpu_opp() - Set the OPP of the CPU. | ||
235 | * @opp: The OPP to set. | ||
236 | * | ||
237 | * This function sets the OPP of the CPU. | ||
238 | */ | ||
239 | int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp) | ||
240 | { | ||
241 | return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp); | ||
242 | } | ||
243 | EXPORT_SYMBOL(prcmu_set_cpu_opp); | ||
244 | |||
245 | /** | ||
246 | * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU. | ||
247 | * @ape_opp: The APE OPP to set. | ||
248 | * @cpu_opp: The CPU OPP to set. | ||
249 | * | ||
250 | * This function sets the OPPs of the APE and the CPU. | ||
251 | */ | ||
252 | int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, | ||
253 | enum prcmu_cpu_opp cpu_opp) | ||
254 | { | ||
255 | return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp); | ||
256 | } | ||
257 | EXPORT_SYMBOL(prcmu_set_ape_cpu_opps); | ||
258 | |||
259 | /** | ||
260 | * prcmu_get_ape_opp() - Get the OPP of the APE. | ||
261 | * | ||
262 | * This function gets the OPP of the APE. | ||
263 | */ | ||
264 | enum prcmu_ape_opp prcmu_get_ape_opp(void) | ||
265 | { | ||
266 | return readb(ACK_MB1_CURR_APEOPP); | ||
267 | } | ||
268 | EXPORT_SYMBOL(prcmu_get_ape_opp); | ||
269 | |||
270 | /** | ||
271 | * prcmu_get_cpu_opp() - Get the OPP of the CPU. | ||
272 | * | ||
273 | * This function gets the OPP of the CPU. The OPP is specified in %%. | ||
274 | * PRCMU_OPP_EXT is a special OPP value, not specified in %%. | ||
275 | */ | ||
276 | int prcmu_get_cpu_opp(void) | ||
277 | { | ||
278 | return readb(ACK_MB1_CURR_ARMOPP); | ||
279 | } | ||
280 | EXPORT_SYMBOL(prcmu_get_cpu_opp); | ||
281 | |||
282 | bool prcmu_has_arm_maxopp(void) | ||
283 | { | ||
284 | return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK) | ||
285 | == PRCM_AVS_ISMODEENABLE_MASK; | ||
286 | } | ||
287 | |||
148 | static void read_mailbox_0(void) | 288 | static void read_mailbox_0(void) |
149 | { | 289 | { |
150 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); | 290 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); |
@@ -152,6 +292,9 @@ static void read_mailbox_0(void) | |||
152 | 292 | ||
153 | static void read_mailbox_1(void) | 293 | static void read_mailbox_1(void) |
154 | { | 294 | { |
295 | mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP); | ||
296 | mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP); | ||
297 | complete(&mb1_transfer.work); | ||
155 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); | 298 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); |
156 | } | 299 | } |
157 | 300 | ||
@@ -217,15 +360,35 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data) | |||
217 | return IRQ_HANDLED; | 360 | return IRQ_HANDLED; |
218 | } | 361 | } |
219 | 362 | ||
363 | void __init prcmu_early_init(void) | ||
364 | { | ||
365 | if (cpu_is_u8500v11() || cpu_is_u8500ed()) { | ||
366 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); | ||
367 | } else if (cpu_is_u8500v2()) { | ||
368 | tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); | ||
369 | } else { | ||
370 | pr_err("prcmu: Unsupported chip version\n"); | ||
371 | BUG(); | ||
372 | } | ||
373 | } | ||
374 | |||
220 | static int __init prcmu_init(void) | 375 | static int __init prcmu_init(void) |
221 | { | 376 | { |
377 | if (cpu_is_u8500ed()) { | ||
378 | pr_err("prcmu: Unsupported chip version\n"); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | mutex_init(&mb1_transfer.lock); | ||
383 | init_completion(&mb1_transfer.work); | ||
222 | mutex_init(&mb5_transfer.lock); | 384 | mutex_init(&mb5_transfer.lock); |
223 | init_completion(&mb5_transfer.work); | 385 | init_completion(&mb5_transfer.work); |
224 | 386 | ||
225 | /* Clean up the mailbox interrupts after pre-kernel code. */ | 387 | /* Clean up the mailbox interrupts after pre-kernel code. */ |
226 | writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); | 388 | writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); |
227 | 389 | ||
228 | return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL); | 390 | return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0, |
391 | "prcmu", NULL); | ||
229 | } | 392 | } |
230 | 393 | ||
231 | arch_initcall(prcmu_init); | 394 | arch_initcall(prcmu_init); |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 4414a01e1e8a..a099efed0e63 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -382,6 +382,12 @@ config CPU_FEROCEON_OLD_ID | |||
382 | for which the CPU ID is equal to the ARM926 ID. | 382 | for which the CPU ID is equal to the ARM926 ID. |
383 | Relevant for Feroceon-1850 and early Feroceon-2850. | 383 | Relevant for Feroceon-1850 and early Feroceon-2850. |
384 | 384 | ||
385 | # Marvell PJ4 | ||
386 | config CPU_PJ4 | ||
387 | bool | ||
388 | select CPU_V7 | ||
389 | select ARM_THUMBEE | ||
390 | |||
385 | # ARMv6 | 391 | # ARMv6 |
386 | config CPU_V6 | 392 | config CPU_V6 |
387 | bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE | 393 | bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE |
@@ -789,7 +795,7 @@ config CACHE_PL310 | |||
789 | 795 | ||
790 | config CACHE_TAUROS2 | 796 | config CACHE_TAUROS2 |
791 | bool "Enable the Tauros2 L2 cache controller" | 797 | bool "Enable the Tauros2 L2 cache controller" |
792 | depends on (ARCH_DOVE || ARCH_MMP) | 798 | depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4) |
793 | default y | 799 | default y |
794 | select OUTER_CACHE | 800 | select OUTER_CACHE |
795 | help | 801 | help |
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 99fa688dfadd..c96fa1b3f49f 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
@@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area) | |||
203 | * - end - virtual end address of region | 203 | * - end - virtual end address of region |
204 | */ | 204 | */ |
205 | v6_dma_inv_range: | 205 | v6_dma_inv_range: |
206 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
207 | ldrb r2, [r0] @ read for ownership | ||
208 | strb r2, [r0] @ write for ownership | ||
209 | #endif | ||
206 | tst r0, #D_CACHE_LINE_SIZE - 1 | 210 | tst r0, #D_CACHE_LINE_SIZE - 1 |
207 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 211 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
208 | #ifdef HARVARD_CACHE | 212 | #ifdef HARVARD_CACHE |
@@ -211,6 +215,10 @@ v6_dma_inv_range: | |||
211 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line | 215 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line |
212 | #endif | 216 | #endif |
213 | tst r1, #D_CACHE_LINE_SIZE - 1 | 217 | tst r1, #D_CACHE_LINE_SIZE - 1 |
218 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
219 | ldrneb r2, [r1, #-1] @ read for ownership | ||
220 | strneb r2, [r1, #-1] @ write for ownership | ||
221 | #endif | ||
214 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 | 222 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 |
215 | #ifdef HARVARD_CACHE | 223 | #ifdef HARVARD_CACHE |
216 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line | 224 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line |
@@ -218,10 +226,6 @@ v6_dma_inv_range: | |||
218 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line | 226 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line |
219 | #endif | 227 | #endif |
220 | 1: | 228 | 1: |
221 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
222 | ldr r2, [r0] @ read for ownership | ||
223 | str r2, [r0] @ write for ownership | ||
224 | #endif | ||
225 | #ifdef HARVARD_CACHE | 229 | #ifdef HARVARD_CACHE |
226 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line | 230 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line |
227 | #else | 231 | #else |
@@ -229,6 +233,10 @@ v6_dma_inv_range: | |||
229 | #endif | 233 | #endif |
230 | add r0, r0, #D_CACHE_LINE_SIZE | 234 | add r0, r0, #D_CACHE_LINE_SIZE |
231 | cmp r0, r1 | 235 | cmp r0, r1 |
236 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
237 | ldrlo r2, [r0] @ read for ownership | ||
238 | strlo r2, [r0] @ write for ownership | ||
239 | #endif | ||
232 | blo 1b | 240 | blo 1b |
233 | mov r0, #0 | 241 | mov r0, #0 |
234 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 242 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
@@ -263,12 +271,12 @@ v6_dma_clean_range: | |||
263 | * - end - virtual end address of region | 271 | * - end - virtual end address of region |
264 | */ | 272 | */ |
265 | ENTRY(v6_dma_flush_range) | 273 | ENTRY(v6_dma_flush_range) |
266 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
267 | 1: | ||
268 | #ifdef CONFIG_DMA_CACHE_RWFO | 274 | #ifdef CONFIG_DMA_CACHE_RWFO |
269 | ldr r2, [r0] @ read for ownership | 275 | ldrb r2, [r0] @ read for ownership |
270 | str r2, [r0] @ write for ownership | 276 | strb r2, [r0] @ write for ownership |
271 | #endif | 277 | #endif |
278 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
279 | 1: | ||
272 | #ifdef HARVARD_CACHE | 280 | #ifdef HARVARD_CACHE |
273 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | 281 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line |
274 | #else | 282 | #else |
@@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range) | |||
276 | #endif | 284 | #endif |
277 | add r0, r0, #D_CACHE_LINE_SIZE | 285 | add r0, r0, #D_CACHE_LINE_SIZE |
278 | cmp r0, r1 | 286 | cmp r0, r1 |
287 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
288 | ldrlob r2, [r0] @ read for ownership | ||
289 | strlob r2, [r0] @ write for ownership | ||
290 | #endif | ||
279 | blo 1b | 291 | blo 1b |
280 | mov r0, #0 | 292 | mov r0, #0 |
281 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 293 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index a3ebf7a4f49b..6136e68ce953 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range) | |||
173 | UNWIND(.fnstart ) | 173 | UNWIND(.fnstart ) |
174 | dcache_line_size r2, r3 | 174 | dcache_line_size r2, r3 |
175 | sub r3, r2, #1 | 175 | sub r3, r2, #1 |
176 | bic r0, r0, r3 | 176 | bic r12, r0, r3 |
177 | 1: | 177 | 1: |
178 | USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification | 178 | USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification |
179 | add r12, r12, r2 | ||
180 | cmp r12, r1 | ||
181 | blo 1b | ||
179 | dsb | 182 | dsb |
180 | USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line | 183 | icache_line_size r2, r3 |
181 | add r0, r0, r2 | 184 | sub r3, r2, #1 |
185 | bic r12, r0, r3 | ||
182 | 2: | 186 | 2: |
183 | cmp r0, r1 | 187 | USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line |
184 | blo 1b | 188 | add r12, r12, r2 |
189 | cmp r12, r1 | ||
190 | blo 2b | ||
191 | 3: | ||
185 | mov r0, #0 | 192 | mov r0, #0 |
186 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable | 193 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable |
187 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB | 194 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB |
@@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range) | |||
194 | * isn't mapped, just try the next page. | 201 | * isn't mapped, just try the next page. |
195 | */ | 202 | */ |
196 | 9001: | 203 | 9001: |
197 | mov r0, r0, lsr #12 | 204 | mov r12, r12, lsr #12 |
198 | mov r0, r0, lsl #12 | 205 | mov r12, r12, lsl #12 |
199 | add r0, r0, #4096 | 206 | add r12, r12, #4096 |
200 | b 2b | 207 | b 3b |
201 | UNWIND(.fnend ) | 208 | UNWIND(.fnend ) |
202 | ENDPROC(v7_coherent_kern_range) | 209 | ENDPROC(v7_coherent_kern_range) |
203 | ENDPROC(v7_coherent_user_range) | 210 | ENDPROC(v7_coherent_user_range) |
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 7d63beaf9745..b795afd0a2c6 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
@@ -61,17 +61,27 @@ | |||
61 | .endm | 61 | .endm |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * cache_line_size - get the cache line size from the CSIDR register | 64 | * dcache_line_size - get the minimum D-cache line size from the CTR register |
65 | * (available on ARMv7+). It assumes that the CSSR register was configured | 65 | * on ARMv7. |
66 | * to access the L1 data cache CSIDR. | ||
67 | */ | 66 | */ |
68 | .macro dcache_line_size, reg, tmp | 67 | .macro dcache_line_size, reg, tmp |
69 | mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR | 68 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr |
70 | and \tmp, \tmp, #7 @ cache line size encoding | 69 | lsr \tmp, \tmp, #16 |
71 | mov \reg, #16 @ size offset | 70 | and \tmp, \tmp, #0xf @ cache line size encoding |
71 | mov \reg, #4 @ bytes per word | ||
72 | mov \reg, \reg, lsl \tmp @ actual cache line size | 72 | mov \reg, \reg, lsl \tmp @ actual cache line size |
73 | .endm | 73 | .endm |
74 | 74 | ||
75 | /* | ||
76 | * icache_line_size - get the minimum I-cache line size from the CTR register | ||
77 | * on ARMv7. | ||
78 | */ | ||
79 | .macro icache_line_size, reg, tmp | ||
80 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr | ||
81 | and \tmp, \tmp, #0xf @ cache line size encoding | ||
82 | mov \reg, #4 @ bytes per word | ||
83 | mov \reg, \reg, lsl \tmp @ actual cache line size | ||
84 | .endm | ||
75 | 85 | ||
76 | /* | 86 | /* |
77 | * Sanity check the PTE configuration for the code below - which makes | 87 | * Sanity check the PTE configuration for the code below - which makes |
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 85e6fd212a41..eda4e3a11a3d 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -119,7 +119,7 @@ static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
122 | pin_cfg_t cfg) | 122 | pin_cfg_t cfg, bool sleep) |
123 | { | 123 | { |
124 | static const char *afnames[] = { | 124 | static const char *afnames[] = { |
125 | [NMK_GPIO_ALT_GPIO] = "GPIO", | 125 | [NMK_GPIO_ALT_GPIO] = "GPIO", |
@@ -145,11 +145,34 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
145 | int output = PIN_DIR(cfg); | 145 | int output = PIN_DIR(cfg); |
146 | int val = PIN_VAL(cfg); | 146 | int val = PIN_VAL(cfg); |
147 | 147 | ||
148 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n", | 148 | dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", |
149 | pin, afnames[af], pullnames[pull], slpmnames[slpm], | 149 | pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], |
150 | output ? "output " : "input", | 150 | output ? "output " : "input", |
151 | output ? (val ? "high" : "low") : ""); | 151 | output ? (val ? "high" : "low") : ""); |
152 | 152 | ||
153 | if (sleep) { | ||
154 | int slpm_pull = PIN_SLPM_PULL(cfg); | ||
155 | int slpm_output = PIN_SLPM_DIR(cfg); | ||
156 | int slpm_val = PIN_SLPM_VAL(cfg); | ||
157 | |||
158 | /* | ||
159 | * The SLPM_* values are normal values + 1 to allow zero to | ||
160 | * mean "same as normal". | ||
161 | */ | ||
162 | if (slpm_pull) | ||
163 | pull = slpm_pull - 1; | ||
164 | if (slpm_output) | ||
165 | output = slpm_output - 1; | ||
166 | if (slpm_val) | ||
167 | val = slpm_val - 1; | ||
168 | |||
169 | dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", | ||
170 | pin, | ||
171 | slpm_pull ? pullnames[pull] : "same", | ||
172 | slpm_output ? (output ? "output" : "input") : "same", | ||
173 | slpm_val ? (val ? "high" : "low") : "same"); | ||
174 | } | ||
175 | |||
153 | if (output) | 176 | if (output) |
154 | __nmk_gpio_make_output(nmk_chip, offset, val); | 177 | __nmk_gpio_make_output(nmk_chip, offset, val); |
155 | else { | 178 | else { |
@@ -175,7 +198,7 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
175 | * side-effects. The gpio can be manipulated later using standard GPIO API | 198 | * side-effects. The gpio can be manipulated later using standard GPIO API |
176 | * calls. | 199 | * calls. |
177 | */ | 200 | */ |
178 | int nmk_config_pin(pin_cfg_t cfg) | 201 | int nmk_config_pin(pin_cfg_t cfg, bool sleep) |
179 | { | 202 | { |
180 | struct nmk_gpio_chip *nmk_chip; | 203 | struct nmk_gpio_chip *nmk_chip; |
181 | int gpio = PIN_NUM(cfg); | 204 | int gpio = PIN_NUM(cfg); |
@@ -186,7 +209,7 @@ int nmk_config_pin(pin_cfg_t cfg) | |||
186 | return -EINVAL; | 209 | return -EINVAL; |
187 | 210 | ||
188 | spin_lock_irqsave(&nmk_chip->lock, flags); | 211 | spin_lock_irqsave(&nmk_chip->lock, flags); |
189 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg); | 212 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg, sleep); |
190 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 213 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
191 | 214 | ||
192 | return 0; | 215 | return 0; |
@@ -207,7 +230,7 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) | |||
207 | int i; | 230 | int i; |
208 | 231 | ||
209 | for (i = 0; i < num; i++) { | 232 | for (i = 0; i < num; i++) { |
210 | int ret = nmk_config_pin(cfgs[i]); | 233 | ret = nmk_config_pin(cfgs[i], false); |
211 | if (ret) | 234 | if (ret) |
212 | break; | 235 | break; |
213 | } | 236 | } |
@@ -216,6 +239,21 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) | |||
216 | } | 239 | } |
217 | EXPORT_SYMBOL(nmk_config_pins); | 240 | EXPORT_SYMBOL(nmk_config_pins); |
218 | 241 | ||
242 | int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num) | ||
243 | { | ||
244 | int ret = 0; | ||
245 | int i; | ||
246 | |||
247 | for (i = 0; i < num; i++) { | ||
248 | ret = nmk_config_pin(cfgs[i], true); | ||
249 | if (ret) | ||
250 | break; | ||
251 | } | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | EXPORT_SYMBOL(nmk_config_pins_sleep); | ||
256 | |||
219 | /** | 257 | /** |
220 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin | 258 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin |
221 | * @gpio: pin number | 259 | * @gpio: pin number |
@@ -634,7 +672,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
634 | 672 | ||
635 | chip = &nmk_chip->chip; | 673 | chip = &nmk_chip->chip; |
636 | chip->base = pdata->first_gpio; | 674 | chip->base = pdata->first_gpio; |
637 | chip->label = pdata->name; | 675 | chip->label = pdata->name ?: dev_name(&dev->dev); |
638 | chip->dev = &dev->dev; | 676 | chip->dev = &dev->dev; |
639 | chip->owner = THIS_MODULE; | 677 | chip->owner = THIS_MODULE; |
640 | 678 | ||
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h index 8c5ae3f2acf8..05a3936ae6d1 100644 --- a/arch/arm/plat-nomadik/include/plat/pincfg.h +++ b/arch/arm/plat-nomadik/include/plat/pincfg.h | |||
@@ -19,16 +19,22 @@ | |||
19 | * bit 9..10 - Alternate Function Selection | 19 | * bit 9..10 - Alternate Function Selection |
20 | * bit 11..12 - Pull up/down state | 20 | * bit 11..12 - Pull up/down state |
21 | * bit 13 - Sleep mode behaviour | 21 | * bit 13 - Sleep mode behaviour |
22 | * bit 14 - (sleep mode) Direction | 22 | * bit 14 - Direction |
23 | * bit 15 - (sleep mode) Value (if output) | 23 | * bit 15 - Value (if output) |
24 | * bit 16..18 - SLPM pull up/down state | ||
25 | * bit 19..20 - SLPM direction | ||
26 | * bit 21..22 - SLPM Value (if output) | ||
24 | * | 27 | * |
25 | * to facilitate the definition, the following macros are provided | 28 | * to facilitate the definition, the following macros are provided |
26 | * | 29 | * |
27 | * PIN_CFG_DEFAULT - default config (0): | 30 | * PIN_CFG_DEFAULT - default config (0): |
28 | * pull up/down = disabled | 31 | * pull up/down = disabled |
29 | * sleep mode = input/wakeup | 32 | * sleep mode = input/wakeup |
30 | * (sleep mode) direction = input | 33 | * direction = input |
31 | * (sleep mode) value = low | 34 | * value = low |
35 | * SLPM direction = same as normal | ||
36 | * SLPM pull = same as normal | ||
37 | * SLPM value = same as normal | ||
32 | * | 38 | * |
33 | * PIN_CFG - default config with alternate function | 39 | * PIN_CFG - default config with alternate function |
34 | * PIN_CFG_PULL - default config with alternate function and pull up/down | 40 | * PIN_CFG_PULL - default config with alternate function and pull up/down |
@@ -75,30 +81,64 @@ typedef unsigned long pin_cfg_t; | |||
75 | #define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) | 81 | #define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) |
76 | #define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) | 82 | #define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) |
77 | 83 | ||
78 | /* Shortcuts. Use these instead of separate DIR and VAL. */ | 84 | #define PIN_SLPM_PULL_SHIFT 16 |
79 | #define PIN_INPUT PIN_DIR_INPUT | 85 | #define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT) |
86 | #define PIN_SLPM_PULL(x) \ | ||
87 | (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT) | ||
88 | #define PIN_SLPM_PULL_NONE \ | ||
89 | ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT) | ||
90 | #define PIN_SLPM_PULL_UP \ | ||
91 | ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT) | ||
92 | #define PIN_SLPM_PULL_DOWN \ | ||
93 | ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT) | ||
94 | |||
95 | #define PIN_SLPM_DIR_SHIFT 19 | ||
96 | #define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT) | ||
97 | #define PIN_SLPM_DIR(x) \ | ||
98 | (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT) | ||
99 | #define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT) | ||
100 | #define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT) | ||
101 | |||
102 | #define PIN_SLPM_VAL_SHIFT 21 | ||
103 | #define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT) | ||
104 | #define PIN_SLPM_VAL(x) \ | ||
105 | (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT) | ||
106 | #define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT) | ||
107 | #define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT) | ||
108 | |||
109 | /* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ | ||
110 | #define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) | ||
111 | #define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) | ||
112 | #define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE) | ||
80 | #define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) | 113 | #define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) |
81 | #define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) | 114 | #define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) |
82 | 115 | ||
83 | /* | 116 | #define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN) |
84 | * These are the same as the ones above, but should make more sense to the | 117 | #define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP) |
85 | * reader when seen along with a setting a pin to AF mode. | 118 | #define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE) |
86 | */ | 119 | #define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW) |
87 | #define PIN_SLPM_INPUT PIN_INPUT | 120 | #define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH) |
88 | #define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW | ||
89 | #define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH | ||
90 | 121 | ||
91 | #define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT) | 122 | #define PIN_CFG_DEFAULT (0) |
92 | 123 | ||
93 | #define PIN_CFG(num, alt) \ | 124 | #define PIN_CFG(num, alt) \ |
94 | (PIN_CFG_DEFAULT |\ | 125 | (PIN_CFG_DEFAULT |\ |
95 | (PIN_NUM(num) | PIN_##alt)) | 126 | (PIN_NUM(num) | PIN_##alt)) |
96 | 127 | ||
128 | #define PIN_CFG_INPUT(num, alt, pull) \ | ||
129 | (PIN_CFG_DEFAULT |\ | ||
130 | (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull)) | ||
131 | |||
132 | #define PIN_CFG_OUTPUT(num, alt, val) \ | ||
133 | (PIN_CFG_DEFAULT |\ | ||
134 | (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) | ||
135 | |||
97 | #define PIN_CFG_PULL(num, alt, pull) \ | 136 | #define PIN_CFG_PULL(num, alt, pull) \ |
98 | ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ | 137 | ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ |
99 | (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) | 138 | (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) |
100 | 139 | ||
101 | extern int nmk_config_pin(pin_cfg_t cfg); | 140 | extern int nmk_config_pin(pin_cfg_t cfg, bool sleep); |
102 | extern int nmk_config_pins(pin_cfg_t *cfgs, int num); | 141 | extern int nmk_config_pins(pin_cfg_t *cfgs, int num); |
142 | extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num); | ||
103 | 143 | ||
104 | #endif | 144 | #endif |
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 155fe43a672b..8722a136f3a5 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/err.h> | ||
19 | 20 | ||
20 | #include <plat/common.h> | 21 | #include <plat/common.h> |
21 | #include <plat/board.h> | 22 | #include <plat/board.h> |
@@ -164,7 +165,7 @@ static int __init omap_init_clocksource_32k(void) | |||
164 | return -ENODEV; | 165 | return -ENODEV; |
165 | 166 | ||
166 | sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); | 167 | sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); |
167 | if (sync_32k_ick) | 168 | if (!IS_ERR(sync_32k_ick)) |
168 | clk_enable(sync_32k_ick); | 169 | clk_enable(sync_32k_ick); |
169 | 170 | ||
170 | clocksource_32k.mult = clocksource_hz2mult(32768, | 171 | clocksource_32k.mult = clocksource_hz2mult(32768, |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e2c8eebe6b3a..74dac419d328 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -166,7 +166,7 @@ static void __init omap_detect_sram(void) | |||
166 | cpu_is_omap1710()) | 166 | cpu_is_omap1710()) |
167 | omap_sram_size = 0x4000; /* 16K */ | 167 | omap_sram_size = 0x4000; /* 16K */ |
168 | else if (cpu_is_omap1611()) | 168 | else if (cpu_is_omap1611()) |
169 | omap_sram_size = 0x3e800; /* 250K */ | 169 | omap_sram_size = SZ_256K; |
170 | else { | 170 | else { |
171 | printk(KERN_ERR "Could not detect SRAM size\n"); | 171 | printk(KERN_ERR "Could not detect SRAM size\n"); |
172 | omap_sram_size = 0x4000; | 172 | omap_sram_size = 0x4000; |
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile index 4aacdd12c9cc..3aca5ba0f876 100644 --- a/arch/arm/plat-pxa/Makefile +++ b/arch/arm/plat-pxa/Makefile | |||
@@ -6,6 +6,7 @@ obj-y := dma.o | |||
6 | 6 | ||
7 | obj-$(CONFIG_GENERIC_GPIO) += gpio.o | 7 | obj-$(CONFIG_GENERIC_GPIO) += gpio.o |
8 | obj-$(CONFIG_PXA3xx) += mfp.o | 8 | obj-$(CONFIG_PXA3xx) += mfp.o |
9 | obj-$(CONFIG_PXA95x) += mfp.o | ||
9 | obj-$(CONFIG_ARCH_MMP) += mfp.o | 10 | obj-$(CONFIG_ARCH_MMP) += mfp.o |
10 | 11 | ||
11 | obj-$(CONFIG_HAVE_PWM) += pwm.o | 12 | obj-$(CONFIG_HAVE_PWM) += pwm.o |
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h index 9e604c80618f..75f656471240 100644 --- a/arch/arm/plat-pxa/include/plat/mfp.h +++ b/arch/arm/plat-pxa/include/plat/mfp.h | |||
@@ -423,7 +423,7 @@ typedef unsigned long mfp_cfg_t; | |||
423 | ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\ | 423 | ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\ |
424 | (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm)) | 424 | (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm)) |
425 | 425 | ||
426 | #if defined(CONFIG_PXA3xx) || defined(CONFIG_ARCH_MMP) | 426 | #if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) || defined(CONFIG_ARCH_MMP) |
427 | /* | 427 | /* |
428 | * each MFP pin will have a MFPR register, since the offset of the | 428 | * each MFP pin will have a MFPR register, since the offset of the |
429 | * register varies between processors, the processor specific code | 429 | * register varies between processors, the processor specific code |
@@ -470,6 +470,6 @@ void mfp_write(int mfp, unsigned long mfpr_val); | |||
470 | void mfp_config(unsigned long *mfp_cfgs, int num); | 470 | void mfp_config(unsigned long *mfp_cfgs, int num); |
471 | void mfp_config_run(void); | 471 | void mfp_config_run(void); |
472 | void mfp_config_lpm(void); | 472 | void mfp_config_lpm(void); |
473 | #endif /* CONFIG_PXA3xx || CONFIG_ARCH_MMP */ | 473 | #endif /* CONFIG_PXA3xx || CONFIG_PXA95x || CONFIG_ARCH_MMP */ |
474 | 474 | ||
475 | #endif /* __ASM_PLAT_MFP_H */ | 475 | #endif /* __ASM_PLAT_MFP_H */ |
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 76d0858c3cbb..4a10c0f684b2 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c | |||
@@ -88,7 +88,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
88 | { | 88 | { |
89 | .idcode = 0x32440000, | 89 | .idcode = 0x32440000, |
90 | .idmask = 0xffffffff, | 90 | .idmask = 0xffffffff, |
91 | .map_io = s3c244x_map_io, | 91 | .map_io = s3c2440_map_io, |
92 | .init_clocks = s3c244x_init_clocks, | 92 | .init_clocks = s3c244x_init_clocks, |
93 | .init_uarts = s3c244x_init_uarts, | 93 | .init_uarts = s3c244x_init_uarts, |
94 | .init = s3c2440_init, | 94 | .init = s3c2440_init, |
@@ -97,7 +97,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
97 | { | 97 | { |
98 | .idcode = 0x32440001, | 98 | .idcode = 0x32440001, |
99 | .idmask = 0xffffffff, | 99 | .idmask = 0xffffffff, |
100 | .map_io = s3c244x_map_io, | 100 | .map_io = s3c2440_map_io, |
101 | .init_clocks = s3c244x_init_clocks, | 101 | .init_clocks = s3c244x_init_clocks, |
102 | .init_uarts = s3c244x_init_uarts, | 102 | .init_uarts = s3c244x_init_uarts, |
103 | .init = s3c2440_init, | 103 | .init = s3c2440_init, |
@@ -106,7 +106,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
106 | { | 106 | { |
107 | .idcode = 0x32440aaa, | 107 | .idcode = 0x32440aaa, |
108 | .idmask = 0xffffffff, | 108 | .idmask = 0xffffffff, |
109 | .map_io = s3c244x_map_io, | 109 | .map_io = s3c2442_map_io, |
110 | .init_clocks = s3c244x_init_clocks, | 110 | .init_clocks = s3c244x_init_clocks, |
111 | .init_uarts = s3c244x_init_uarts, | 111 | .init_uarts = s3c244x_init_uarts, |
112 | .init = s3c2442_init, | 112 | .init = s3c2442_init, |
@@ -115,7 +115,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
115 | { | 115 | { |
116 | .idcode = 0x32440aab, | 116 | .idcode = 0x32440aab, |
117 | .idmask = 0xffffffff, | 117 | .idmask = 0xffffffff, |
118 | .map_io = s3c244x_map_io, | 118 | .map_io = s3c2442_map_io, |
119 | .init_clocks = s3c244x_init_clocks, | 119 | .init_clocks = s3c244x_init_clocks, |
120 | .init_uarts = s3c244x_init_uarts, | 120 | .init_uarts = s3c244x_init_uarts, |
121 | .init = s3c2442_init, | 121 | .init = s3c2442_init, |
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 24c6f5a30596..243b6411050d 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c | |||
@@ -82,8 +82,6 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { | |||
82 | struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { | 82 | struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { |
83 | .set_config = s3c_gpio_setcfg_s3c24xx, | 83 | .set_config = s3c_gpio_setcfg_s3c24xx, |
84 | .get_config = s3c_gpio_getcfg_s3c24xx, | 84 | .get_config = s3c_gpio_getcfg_s3c24xx, |
85 | .set_pull = s3c_gpio_setpull_1up, | ||
86 | .get_pull = s3c_gpio_getpull_1up, | ||
87 | }; | 85 | }; |
88 | 86 | ||
89 | struct s3c_gpio_chip s3c24xx_gpios[] = { | 87 | struct s3c_gpio_chip s3c24xx_gpios[] = { |
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h index 307248d1ccbb..89e8d0a25f87 100644 --- a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h +++ b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h | |||
@@ -21,17 +21,22 @@ extern void s3c244x_init_clocks(int xtal); | |||
21 | #else | 21 | #else |
22 | #define s3c244x_init_clocks NULL | 22 | #define s3c244x_init_clocks NULL |
23 | #define s3c244x_init_uarts NULL | 23 | #define s3c244x_init_uarts NULL |
24 | #define s3c244x_map_io NULL | ||
25 | #endif | 24 | #endif |
26 | 25 | ||
27 | #ifdef CONFIG_CPU_S3C2440 | 26 | #ifdef CONFIG_CPU_S3C2440 |
28 | extern int s3c2440_init(void); | 27 | extern int s3c2440_init(void); |
28 | |||
29 | extern void s3c2440_map_io(void); | ||
29 | #else | 30 | #else |
30 | #define s3c2440_init NULL | 31 | #define s3c2440_init NULL |
32 | #define s3c2440_map_io NULL | ||
31 | #endif | 33 | #endif |
32 | 34 | ||
33 | #ifdef CONFIG_CPU_S3C2442 | 35 | #ifdef CONFIG_CPU_S3C2442 |
34 | extern int s3c2442_init(void); | 36 | extern int s3c2442_init(void); |
37 | |||
38 | extern void s3c2442_map_io(void); | ||
35 | #else | 39 | #else |
36 | #define s3c2442_init NULL | 40 | #define s3c2442_init NULL |
41 | #define s3c2442_map_io NULL | ||
37 | #endif | 42 | #endif |
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index b732b773b9af..0aa32f242ee4 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c | |||
@@ -280,18 +280,17 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, | |||
280 | } | 280 | } |
281 | #endif | 281 | #endif |
282 | 282 | ||
283 | #ifdef CONFIG_S3C_GPIO_PULL_UP | 283 | #if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN) |
284 | int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | 284 | static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip, |
285 | unsigned int off, s3c_gpio_pull_t pull) | 285 | unsigned int off, s3c_gpio_pull_t pull, |
286 | s3c_gpio_pull_t updown) | ||
286 | { | 287 | { |
287 | void __iomem *reg = chip->base + 0x08; | 288 | void __iomem *reg = chip->base + 0x08; |
288 | u32 pup = __raw_readl(reg); | 289 | u32 pup = __raw_readl(reg); |
289 | 290 | ||
290 | pup = __raw_readl(reg); | 291 | if (pull == updown) |
291 | |||
292 | if (pup == S3C_GPIO_PULL_UP) | ||
293 | pup &= ~(1 << off); | 292 | pup &= ~(1 << off); |
294 | else if (pup == S3C_GPIO_PULL_NONE) | 293 | else if (pull == S3C_GPIO_PULL_NONE) |
295 | pup |= (1 << off); | 294 | pup |= (1 << off); |
296 | else | 295 | else |
297 | return -EINVAL; | 296 | return -EINVAL; |
@@ -300,17 +299,45 @@ int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | |||
300 | return 0; | 299 | return 0; |
301 | } | 300 | } |
302 | 301 | ||
303 | s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | 302 | static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip, |
304 | unsigned int off) | 303 | unsigned int off, s3c_gpio_pull_t updown) |
305 | { | 304 | { |
306 | void __iomem *reg = chip->base + 0x08; | 305 | void __iomem *reg = chip->base + 0x08; |
307 | u32 pup = __raw_readl(reg); | 306 | u32 pup = __raw_readl(reg); |
308 | 307 | ||
309 | pup &= (1 << off); | 308 | pup &= (1 << off); |
310 | return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP; | 309 | return pup ? S3C_GPIO_PULL_NONE : updown; |
310 | } | ||
311 | #endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */ | ||
312 | |||
313 | #ifdef CONFIG_S3C_GPIO_PULL_UP | ||
314 | s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | ||
315 | unsigned int off) | ||
316 | { | ||
317 | return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); | ||
318 | } | ||
319 | |||
320 | int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | ||
321 | unsigned int off, s3c_gpio_pull_t pull) | ||
322 | { | ||
323 | return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); | ||
311 | } | 324 | } |
312 | #endif /* CONFIG_S3C_GPIO_PULL_UP */ | 325 | #endif /* CONFIG_S3C_GPIO_PULL_UP */ |
313 | 326 | ||
327 | #ifdef CONFIG_S3C_GPIO_PULL_DOWN | ||
328 | s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, | ||
329 | unsigned int off) | ||
330 | { | ||
331 | return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); | ||
332 | } | ||
333 | |||
334 | int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, | ||
335 | unsigned int off, s3c_gpio_pull_t pull) | ||
336 | { | ||
337 | return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); | ||
338 | } | ||
339 | #endif /* CONFIG_S3C_GPIO_PULL_DOWN */ | ||
340 | |||
314 | #ifdef CONFIG_S5P_GPIO_DRVSTR | 341 | #ifdef CONFIG_S5P_GPIO_DRVSTR |
315 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | 342 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) |
316 | { | 343 | { |
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index 8fd65d8b5863..0d2c5703f1ee 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h | |||
@@ -210,6 +210,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | |||
210 | unsigned int off); | 210 | unsigned int off); |
211 | 211 | ||
212 | /** | 212 | /** |
213 | * s3c_gpio_getpull_1down() - Get configuration for choice of down or none | ||
214 | * @chip: The gpio chip that the GPIO pin belongs to | ||
215 | * @off: The offset to the pin to get the configuration of. | ||
216 | * | ||
217 | * This helper function reads the state of the pull-down resistor for the | ||
218 | * given GPIO in the same case as s3c_gpio_setpull_1down. | ||
219 | */ | ||
220 | extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, | ||
221 | unsigned int off); | ||
222 | |||
223 | /** | ||
213 | * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. | 224 | * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. |
214 | * @chip: The gpio chip that is being configured. | 225 | * @chip: The gpio chip that is being configured. |
215 | * @off: The offset for the GPIO being configured. | 226 | * @off: The offset for the GPIO being configured. |
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c index 9768cf7e83d7..9696ddc238c9 100644 --- a/arch/arm/plat-versatile/sched-clock.c +++ b/arch/arm/plat-versatile/sched-clock.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | #include <linux/cnt32_to_63.h> | 21 | #include <linux/cnt32_to_63.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/sched.h> | ||
23 | #include <asm/div64.h> | 24 | #include <asm/div64.h> |
24 | 25 | ||
25 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 55590a4d87c9..2fea897ebeb1 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
@@ -12,7 +12,7 @@ | |||
12 | # | 12 | # |
13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
14 | # | 14 | # |
15 | # Last update: Thu Sep 9 22:43:01 2010 | 15 | # Last update: Sun Dec 12 23:24:27 2010 |
16 | # | 16 | # |
17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
18 | # | 18 | # |
@@ -2321,7 +2321,7 @@ mx31txtr MACH_MX31TXTR MX31TXTR 2332 | |||
2321 | u380 MACH_U380 U380 2333 | 2321 | u380 MACH_U380 U380 2333 |
2322 | oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 | 2322 | oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 |
2323 | npcmx50 MACH_NPCMX50 NPCMX50 2335 | 2323 | npcmx50 MACH_NPCMX50 NPCMX50 2335 |
2324 | mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336 | 2324 | mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336 |
2325 | mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 | 2325 | mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 |
2326 | riom MACH_RIOM RIOM 2338 | 2326 | riom MACH_RIOM RIOM 2338 |
2327 | comcas MACH_COMCAS COMCAS 2339 | 2327 | comcas MACH_COMCAS COMCAS 2339 |
@@ -2355,7 +2355,7 @@ at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366 | |||
2355 | csb732 MACH_CSB732 CSB732 2367 | 2355 | csb732 MACH_CSB732 CSB732 2367 |
2356 | u8500 MACH_U8500 U8500 2368 | 2356 | u8500 MACH_U8500 U8500 2368 |
2357 | huqiu MACH_HUQIU HUQIU 2369 | 2357 | huqiu MACH_HUQIU HUQIU 2369 |
2358 | mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370 | 2358 | mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370 |
2359 | pmt1g MACH_PMT1G PMT1G 2371 | 2359 | pmt1g MACH_PMT1G PMT1G 2371 |
2360 | htcelf MACH_HTCELF HTCELF 2372 | 2360 | htcelf MACH_HTCELF HTCELF 2372 |
2361 | armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 | 2361 | armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 |
@@ -2971,7 +2971,7 @@ premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985 | |||
2971 | wasabi MACH_WASABI WASABI 2986 | 2971 | wasabi MACH_WASABI WASABI 2986 |
2972 | vivow MACH_VIVOW VIVOW 2987 | 2972 | vivow MACH_VIVOW VIVOW 2987 |
2973 | mx50_rdp MACH_MX50_RDP MX50_RDP 2988 | 2973 | mx50_rdp MACH_MX50_RDP MX50_RDP 2988 |
2974 | universal MACH_UNIVERSAL UNIVERSAL 2989 | 2974 | universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989 |
2975 | real6410 MACH_REAL6410 REAL6410 2990 | 2975 | real6410 MACH_REAL6410 REAL6410 2990 |
2976 | spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 | 2976 | spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 |
2977 | ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 | 2977 | ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 |
@@ -3044,3 +3044,178 @@ harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059 | |||
3044 | msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 | 3044 | msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 |
3045 | spear900 MACH_SPEAR900 SPEAR900 3061 | 3045 | spear900 MACH_SPEAR900 SPEAR900 3061 |
3046 | pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 | 3046 | pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 |
3047 | rdstor MACH_RDSTOR RDSTOR 3063 | ||
3048 | usdloader MACH_USDLOADER USDLOADER 3064 | ||
3049 | tsoploader MACH_TSOPLOADER TSOPLOADER 3065 | ||
3050 | kronos MACH_KRONOS KRONOS 3066 | ||
3051 | ffcore MACH_FFCORE FFCORE 3067 | ||
3052 | mone MACH_MONE MONE 3068 | ||
3053 | unit2s MACH_UNIT2S UNIT2S 3069 | ||
3054 | acer_a5 MACH_ACER_A5 ACER_A5 3070 | ||
3055 | etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071 | ||
3056 | stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072 | ||
3057 | p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073 | ||
3058 | tulip MACH_TULIP TULIP 3074 | ||
3059 | sunflower MACH_SUNFLOWER SUNFLOWER 3075 | ||
3060 | rib MACH_RIB RIB 3076 | ||
3061 | clod MACH_CLOD CLOD 3077 | ||
3062 | rump MACH_RUMP RUMP 3078 | ||
3063 | tenderloin MACH_TENDERLOIN TENDERLOIN 3079 | ||
3064 | shortloin MACH_SHORTLOIN SHORTLOIN 3080 | ||
3065 | crespo MACH_CRESPO CRESPO 3081 | ||
3066 | antares MACH_ANTARES ANTARES 3082 | ||
3067 | wb40n MACH_WB40N WB40N 3083 | ||
3068 | herring MACH_HERRING HERRING 3084 | ||
3069 | naxy400 MACH_NAXY400 NAXY400 3085 | ||
3070 | naxy1200 MACH_NAXY1200 NAXY1200 3086 | ||
3071 | vpr200 MACH_VPR200 VPR200 3087 | ||
3072 | bug20 MACH_BUG20 BUG20 3088 | ||
3073 | goflexnet MACH_GOFLEXNET GOFLEXNET 3089 | ||
3074 | torbreck MACH_TORBRECK TORBRECK 3090 | ||
3075 | saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091 | ||
3076 | callisto MACH_CALLISTO CALLISTO 3092 | ||
3077 | multhsu MACH_MULTHSU MULTHSU 3093 | ||
3078 | saluda MACH_SALUDA SALUDA 3094 | ||
3079 | pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095 | ||
3080 | vc0718 MACH_VC0718 VC0718 3096 | ||
3081 | mvblx MACH_MVBLX MVBLX 3097 | ||
3082 | inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098 | ||
3083 | inhand_fury MACH_INHAND_FURY INHAND_FURY 3099 | ||
3084 | inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100 | ||
3085 | hdnvp MACH_HDNVP HDNVP 3101 | ||
3086 | softwinner MACH_SOFTWINNER SOFTWINNER 3102 | ||
3087 | prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 | ||
3088 | nas6210 MACH_NAS6210 NAS6210 3104 | ||
3089 | unisdev MACH_UNISDEV UNISDEV 3105 | ||
3090 | sbca11 MACH_SBCA11 SBCA11 3106 | ||
3091 | saga MACH_SAGA SAGA 3107 | ||
3092 | ns_k330 MACH_NS_K330 NS_K330 3108 | ||
3093 | tanna MACH_TANNA TANNA 3109 | ||
3094 | imate8502 MACH_IMATE8502 IMATE8502 3110 | ||
3095 | aspen MACH_ASPEN ASPEN 3111 | ||
3096 | daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112 | ||
3097 | zmx25 MACH_ZMX25 ZMX25 3113 | ||
3098 | maple1 MACH_MAPLE1 MAPLE1 3114 | ||
3099 | qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115 | ||
3100 | qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116 | ||
3101 | abilene MACH_ABILENE ABILENE 3117 | ||
3102 | eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118 | ||
3103 | iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119 | ||
3104 | coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120 | ||
3105 | santiago MACH_SANTIAGO SANTIAGO 3121 | ||
3106 | mx257sol MACH_MX257SOL MX257SOL 3122 | ||
3107 | strasbourg MACH_STRASBOURG STRASBOURG 3123 | ||
3108 | msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124 | ||
3109 | smartqv5 MACH_SMARTQV5 SMARTQV5 3125 | ||
3110 | smartqv3 MACH_SMARTQV3 SMARTQV3 3126 | ||
3111 | smartqv7 MACH_SMARTQV7 SMARTQV7 3127 | ||
3112 | paz00 MACH_PAZ00 PAZ00 3128 | ||
3113 | acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 | ||
3114 | htcwillow MACH_HTCWILLOW HTCWILLOW 3130 | ||
3115 | fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131 | ||
3116 | hdgu MACH_HDGU HDGU 3132 | ||
3117 | pyramid MACH_PYRAMID PYRAMID 3133 | ||
3118 | epiphan MACH_EPIPHAN EPIPHAN 3134 | ||
3119 | omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135 | ||
3120 | gurnard MACH_GURNARD GURNARD 3136 | ||
3121 | gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137 | ||
3122 | bcm2708 MACH_BCM2708 BCM2708 3138 | ||
3123 | mx51_ggc MACH_MX51_GGC MX51_GGC 3139 | ||
3124 | sharespace MACH_SHARESPACE SHARESPACE 3140 | ||
3125 | haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141 | ||
3126 | simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142 | ||
3127 | crux MACH_CRUX CRUX 3143 | ||
3128 | mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144 | ||
3129 | charon MACH_CHARON CHARON 3145 | ||
3130 | picocom3 MACH_PICOCOM3 PICOCOM3 3146 | ||
3131 | picocom4 MACH_PICOCOM4 PICOCOM4 3147 | ||
3132 | serrano MACH_SERRANO SERRANO 3148 | ||
3133 | doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149 | ||
3134 | evsy MACH_EVSY EVSY 3150 | ||
3135 | huashan MACH_HUASHAN HUASHAN 3151 | ||
3136 | lausanne MACH_LAUSANNE LAUSANNE 3152 | ||
3137 | emerald MACH_EMERALD EMERALD 3153 | ||
3138 | tqma35 MACH_TQMA35 TQMA35 3154 | ||
3139 | marvel MACH_MARVEL MARVEL 3155 | ||
3140 | manuae MACH_MANUAE MANUAE 3156 | ||
3141 | chacha MACH_CHACHA CHACHA 3157 | ||
3142 | lemon MACH_LEMON LEMON 3158 | ||
3143 | csc MACH_CSC CSC 3159 | ||
3144 | gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160 | ||
3145 | t20 MACH_T20 T20 3161 | ||
3146 | hdmini MACH_HDMINI HDMINI 3162 | ||
3147 | sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163 | ||
3148 | express MACH_EXPRESS EXPRESS 3164 | ||
3149 | express_kt MACH_EXPRESS_KT EXPRESS_KT 3165 | ||
3150 | maximasp MACH_MAXIMASP MAXIMASP 3166 | ||
3151 | nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167 | ||
3152 | nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168 | ||
3153 | sunfire MACH_SUNFIRE SUNFIRE 3169 | ||
3154 | arowana MACH_AROWANA AROWANA 3170 | ||
3155 | tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171 | ||
3156 | tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172 | ||
3157 | edison MACH_EDISON EDISON 3173 | ||
3158 | svp8500v1 MACH_SVP8500V1 SVP8500V1 3174 | ||
3159 | svp8500v2 MACH_SVP8500V2 SVP8500V2 3175 | ||
3160 | svp5500 MACH_SVP5500 SVP5500 3176 | ||
3161 | b5500 MACH_B5500 B5500 3177 | ||
3162 | s5500 MACH_S5500 S5500 3178 | ||
3163 | icon MACH_ICON ICON 3179 | ||
3164 | elephant MACH_ELEPHANT ELEPHANT 3180 | ||
3165 | msm8x60_fusion MACH_MSM8X60_FUSION MSM8X60_FUSION 3181 | ||
3166 | shooter MACH_SHOOTER SHOOTER 3182 | ||
3167 | spade_lte MACH_SPADE_LTE SPADE_LTE 3183 | ||
3168 | philhwani MACH_PHILHWANI PHILHWANI 3184 | ||
3169 | gsncomm MACH_GSNCOMM GSNCOMM 3185 | ||
3170 | strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186 | ||
3171 | mmm MACH_MMM MMM 3187 | ||
3172 | davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188 | ||
3173 | ag5evm MACH_AG5EVM AG5EVM 3189 | ||
3174 | sc575plc MACH_SC575PLC SC575PLC 3190 | ||
3175 | sc575hmi MACH_SC575IPC SC575IPC 3191 | ||
3176 | omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192 | ||
3177 | g7 MACH_G7 G7 3193 | ||
3178 | top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194 | ||
3179 | top9000_su MACH_TOP9000_SU TOP9000_SU 3195 | ||
3180 | utm300 MACH_UTM300 UTM300 3196 | ||
3181 | tsunagi MACH_TSUNAGI TSUNAGI 3197 | ||
3182 | ts75xx MACH_TS75XX TS75XX 3198 | ||
3183 | msm8x60_fusn_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199 | ||
3184 | ts47xx MACH_TS47XX TS47XX 3200 | ||
3185 | da850_k5 MACH_DA850_K5 DA850_K5 3201 | ||
3186 | ax502 MACH_AX502 AX502 3202 | ||
3187 | igep0032 MACH_IGEP0032 IGEP0032 3203 | ||
3188 | antero MACH_ANTERO ANTERO 3204 | ||
3189 | synergy MACH_SYNERGY SYNERGY 3205 | ||
3190 | ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 | ||
3191 | wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 | ||
3192 | punica MACH_PUNICA PUNICA 3208 | ||
3193 | sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209 | ||
3194 | mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210 | ||
3195 | mackerel MACH_MACKEREL MACKEREL 3211 | ||
3196 | fa9x27 MACH_FA9X27 FA9X27 3213 | ||
3197 | ns2816tb MACH_NS2816TB NS2816TB 3214 | ||
3198 | ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215 | ||
3199 | ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216 | ||
3200 | kaen MACH_KAEN KAEN 3217 | ||
3201 | nv1000 MACH_NV1000 NV1000 3218 | ||
3202 | nuc950ts MACH_NUC950TS NUC950TS 3219 | ||
3203 | nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220 | ||
3204 | ast2200 MACH_AST2200 AST2200 3221 | ||
3205 | lead MACH_LEAD LEAD 3222 | ||
3206 | unino1 MACH_UNINO1 UNINO1 3223 | ||
3207 | greeco MACH_GREECO GREECO 3224 | ||
3208 | verdi MACH_VERDI VERDI 3225 | ||
3209 | dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226 | ||
3210 | quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227 | ||
3211 | abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228 | ||
3212 | svcid MACH_SVCID SVCID 3229 | ||
3213 | msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230 | ||
3214 | msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231 | ||
3215 | icon_g MACH_ICON_G ICON_G 3232 | ||
3216 | mb3 MACH_MB3 MB3 3233 | ||
3217 | gsia18s MACH_GSIA18S GSIA18S 3234 | ||
3218 | pivicc MACH_PIVICC PIVICC 3235 | ||
3219 | pcm048 MACH_PCM048 PCM048 3236 | ||
3220 | dds MACH_DDS DDS 3237 | ||
3221 | chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 | ||
diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c index 0d5d63c91dc3..f28dc99c6f72 100644 --- a/arch/mn10300/kernel/gdb-io-serial.c +++ b/arch/mn10300/kernel/gdb-io-serial.c | |||
@@ -73,7 +73,8 @@ void gdbstub_io_init(void) | |||
73 | GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI; | 73 | GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI; |
74 | 74 | ||
75 | /* permit level 0 IRQs to take place */ | 75 | /* permit level 0 IRQs to take place */ |
76 | local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | 76 | arch_local_change_intr_mask_level( |
77 | NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | ||
77 | } | 78 | } |
78 | 79 | ||
79 | /* | 80 | /* |
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c index 97dfda23342c..abdeea153c89 100644 --- a/arch/mn10300/kernel/gdb-io-ttysm.c +++ b/arch/mn10300/kernel/gdb-io-ttysm.c | |||
@@ -87,7 +87,8 @@ void __init gdbstub_io_init(void) | |||
87 | tmp = *gdbstub_port->_control; | 87 | tmp = *gdbstub_port->_control; |
88 | 88 | ||
89 | /* permit level 0 IRQs only */ | 89 | /* permit level 0 IRQs only */ |
90 | local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | 90 | arch_local_change_intr_mask_level( |
91 | NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | /* | 94 | /* |
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c index a5fc3f05309b..b169d99d9f20 100644 --- a/arch/mn10300/kernel/gdb-stub.c +++ b/arch/mn10300/kernel/gdb-stub.c | |||
@@ -1194,7 +1194,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) | |||
1194 | 1194 | ||
1195 | asm volatile("mov mdr,%0" : "=d"(mdr)); | 1195 | asm volatile("mov mdr,%0" : "=d"(mdr)); |
1196 | local_save_flags(epsw); | 1196 | local_save_flags(epsw); |
1197 | local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | 1197 | arch_local_change_intr_mask_level( |
1198 | NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | ||
1198 | 1199 | ||
1199 | gdbstub_store_fpu(); | 1200 | gdbstub_store_fpu(); |
1200 | 1201 | ||
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 7f217b3a50a8..2e9d78d21fd3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -22,7 +22,8 @@ config SUPERH | |||
22 | select HAVE_SPARSE_IRQ | 22 | select HAVE_SPARSE_IRQ |
23 | select RTC_LIB | 23 | select RTC_LIB |
24 | select GENERIC_ATOMIC64 | 24 | select GENERIC_ATOMIC64 |
25 | select GENERIC_HARDIRQS_NO_DEPRECATED | 25 | # Support the deprecated APIs until MFD and GPIOLIB catch up. |
26 | select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB | ||
26 | help | 27 | help |
27 | The SuperH is a RISC processor targeted for use in embedded systems | 28 | The SuperH is a RISC processor targeted for use in embedded systems |
28 | and consumer electronics; it was also used in the Sega Dreamcast | 29 | and consumer electronics; it was also used in the Sega Dreamcast |
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index 903cd618eb74..d6741fca89a4 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h | |||
@@ -368,8 +368,9 @@ | |||
368 | #define __NR_sendmsg 355 | 368 | #define __NR_sendmsg 355 |
369 | #define __NR_recvmsg 356 | 369 | #define __NR_recvmsg 356 |
370 | #define __NR_recvmmsg 357 | 370 | #define __NR_recvmmsg 357 |
371 | #define __NR_accept4 358 | ||
371 | 372 | ||
372 | #define NR_syscalls 358 | 373 | #define NR_syscalls 359 |
373 | 374 | ||
374 | #ifdef __KERNEL__ | 375 | #ifdef __KERNEL__ |
375 | 376 | ||
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index e872e81add8a..6fc347ebe59d 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S | |||
@@ -375,3 +375,4 @@ ENTRY(sys_call_table) | |||
375 | .long sys_sendmsg /* 355 */ | 375 | .long sys_sendmsg /* 355 */ |
376 | .long sys_recvmsg | 376 | .long sys_recvmsg |
377 | .long sys_recvmmsg | 377 | .long sys_recvmmsg |
378 | .long sys_accept4 | ||
diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index 81cd43432dc0..47eaafad15ce 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h | |||
@@ -39,7 +39,7 @@ struct linux_dev_v2_funcs { | |||
39 | int (*v2_dev_open)(char *devpath); | 39 | int (*v2_dev_open)(char *devpath); |
40 | void (*v2_dev_close)(int d); | 40 | void (*v2_dev_close)(int d); |
41 | int (*v2_dev_read)(int d, char *buf, int nbytes); | 41 | int (*v2_dev_read)(int d, char *buf, int nbytes); |
42 | int (*v2_dev_write)(int d, char *buf, int nbytes); | 42 | int (*v2_dev_write)(int d, const char *buf, int nbytes); |
43 | int (*v2_dev_seek)(int d, int hi, int lo); | 43 | int (*v2_dev_seek)(int d, int hi, int lo); |
44 | 44 | ||
45 | /* Never issued (multistage load support) */ | 45 | /* Never issued (multistage load support) */ |
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 51296a6f5005..9e5c64084b86 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h | |||
@@ -60,25 +60,6 @@ extern char *prom_getbootargs(void); | |||
60 | extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); | 60 | extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); |
61 | extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); | 61 | extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); |
62 | 62 | ||
63 | /* Device operations. */ | ||
64 | |||
65 | /* Open the device described by the passed string. Note, that the format | ||
66 | * of the string is different on V0 vs. V2->higher proms. The caller must | ||
67 | * know what he/she is doing! Returns the device descriptor, an int. | ||
68 | */ | ||
69 | extern int prom_devopen(char *device_string); | ||
70 | |||
71 | /* Close a previously opened device described by the passed integer | ||
72 | * descriptor. | ||
73 | */ | ||
74 | extern int prom_devclose(int device_handle); | ||
75 | |||
76 | /* Do a seek operation on the device described by the passed integer | ||
77 | * descriptor. | ||
78 | */ | ||
79 | extern void prom_seek(int device_handle, unsigned int seek_hival, | ||
80 | unsigned int seek_lowval); | ||
81 | |||
82 | /* Miscellaneous routines, don't really fit in any category per se. */ | 63 | /* Miscellaneous routines, don't really fit in any category per se. */ |
83 | 64 | ||
84 | /* Reboot the machine with the command line passed. */ | 65 | /* Reboot the machine with the command line passed. */ |
@@ -121,19 +102,8 @@ extern int prom_getrev(void); | |||
121 | /* Get the prom firmware revision. */ | 102 | /* Get the prom firmware revision. */ |
122 | extern int prom_getprev(void); | 103 | extern int prom_getprev(void); |
123 | 104 | ||
124 | /* Character operations to/from the console.... */ | 105 | /* Write a buffer of characters to the console. */ |
125 | 106 | extern void prom_console_write_buf(const char *buf, int len); | |
126 | /* Non-blocking get character from console. */ | ||
127 | extern int prom_nbgetchar(void); | ||
128 | |||
129 | /* Non-blocking put character to console. */ | ||
130 | extern int prom_nbputchar(char character); | ||
131 | |||
132 | /* Blocking get character from console. */ | ||
133 | extern char prom_getchar(void); | ||
134 | |||
135 | /* Blocking put character to console. */ | ||
136 | extern void prom_putchar(char character); | ||
137 | 107 | ||
138 | /* Prom's internal routines, don't use in kernel/boot code. */ | 108 | /* Prom's internal routines, don't use in kernel/boot code. */ |
139 | extern void prom_printf(const char *fmt, ...); | 109 | extern void prom_printf(const char *fmt, ...); |
@@ -238,7 +208,6 @@ extern int prom_node_has_property(phandle node, char *property); | |||
238 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, | 208 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, |
239 | int value_size); | 209 | int value_size); |
240 | 210 | ||
241 | extern phandle prom_pathtoinode(char *path); | ||
242 | extern phandle prom_inst2pkg(int); | 211 | extern phandle prom_inst2pkg(int); |
243 | 212 | ||
244 | /* Dorking with Bus ranges... */ | 213 | /* Dorking with Bus ranges... */ |
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index c9cc078e3e31..8cd0df34e82b 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
@@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack); | |||
67 | /* Boot argument acquisition, returns the boot command line string. */ | 67 | /* Boot argument acquisition, returns the boot command line string. */ |
68 | extern char *prom_getbootargs(void); | 68 | extern char *prom_getbootargs(void); |
69 | 69 | ||
70 | /* Device utilities. */ | ||
71 | |||
72 | /* Device operations. */ | ||
73 | |||
74 | /* Open the device described by the passed string. Note, that the format | ||
75 | * of the string is different on V0 vs. V2->higher proms. The caller must | ||
76 | * know what he/she is doing! Returns the device descriptor, an int. | ||
77 | */ | ||
78 | extern int prom_devopen(const char *device_string); | ||
79 | |||
80 | /* Close a previously opened device described by the passed integer | ||
81 | * descriptor. | ||
82 | */ | ||
83 | extern int prom_devclose(int device_handle); | ||
84 | |||
85 | /* Do a seek operation on the device described by the passed integer | ||
86 | * descriptor. | ||
87 | */ | ||
88 | extern void prom_seek(int device_handle, unsigned int seek_hival, | ||
89 | unsigned int seek_lowval); | ||
90 | |||
91 | /* Miscellaneous routines, don't really fit in any category per se. */ | 70 | /* Miscellaneous routines, don't really fit in any category per se. */ |
92 | 71 | ||
93 | /* Reboot the machine with the command line passed. */ | 72 | /* Reboot the machine with the command line passed. */ |
@@ -109,33 +88,14 @@ extern void prom_halt(void) __attribute__ ((noreturn)); | |||
109 | /* Halt and power-off the machine. */ | 88 | /* Halt and power-off the machine. */ |
110 | extern void prom_halt_power_off(void) __attribute__ ((noreturn)); | 89 | extern void prom_halt_power_off(void) __attribute__ ((noreturn)); |
111 | 90 | ||
112 | /* Set the PROM 'sync' callback function to the passed function pointer. | ||
113 | * When the user gives the 'sync' command at the prom prompt while the | ||
114 | * kernel is still active, the prom will call this routine. | ||
115 | * | ||
116 | */ | ||
117 | typedef int (*callback_func_t)(long *cmd); | ||
118 | extern void prom_setcallback(callback_func_t func_ptr); | ||
119 | |||
120 | /* Acquire the IDPROM of the root node in the prom device tree. This | 91 | /* Acquire the IDPROM of the root node in the prom device tree. This |
121 | * gets passed a buffer where you would like it stuffed. The return value | 92 | * gets passed a buffer where you would like it stuffed. The return value |
122 | * is the format type of this idprom or 0xff on error. | 93 | * is the format type of this idprom or 0xff on error. |
123 | */ | 94 | */ |
124 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); | 95 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); |
125 | 96 | ||
126 | /* Character operations to/from the console.... */ | 97 | /* Write a buffer of characters to the console. */ |
127 | 98 | extern void prom_console_write_buf(const char *buf, int len); | |
128 | /* Non-blocking get character from console. */ | ||
129 | extern int prom_nbgetchar(void); | ||
130 | |||
131 | /* Non-blocking put character to console. */ | ||
132 | extern int prom_nbputchar(char character); | ||
133 | |||
134 | /* Blocking get character from console. */ | ||
135 | extern char prom_getchar(void); | ||
136 | |||
137 | /* Blocking put character to console. */ | ||
138 | extern void prom_putchar(char character); | ||
139 | 99 | ||
140 | /* Prom's internal routines, don't use in kernel/boot code. */ | 100 | /* Prom's internal routines, don't use in kernel/boot code. */ |
141 | extern void prom_printf(const char *fmt, ...); | 101 | extern void prom_printf(const char *fmt, ...); |
@@ -279,9 +239,7 @@ extern phandle prom_finddevice(const char *name); | |||
279 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, | 239 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, |
280 | int value_size); | 240 | int value_size); |
281 | 241 | ||
282 | extern phandle prom_pathtoinode(const char *path); | ||
283 | extern phandle prom_inst2pkg(int); | 242 | extern phandle prom_inst2pkg(int); |
284 | extern int prom_service_exists(const char *service_name); | ||
285 | extern void prom_sun4v_guest_soft_state(void); | 243 | extern void prom_sun4v_guest_soft_state(void); |
286 | 244 | ||
287 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); | 245 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 2d51527d810f..f01c42661ee5 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
114 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { | 114 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { |
115 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); | 115 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); |
116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, | 116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, |
117 | (((1000000 / 100) - 1))); | 117 | (((1000000 / HZ) - 1))); |
118 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); | 118 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); |
119 | 119 | ||
120 | #ifdef CONFIG_SMP | 120 | #ifdef CONFIG_SMP |
@@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
128 | } | 128 | } |
129 | 129 | ||
130 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); | 130 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); |
131 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1))); | 131 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1))); |
132 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); | 132 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); |
133 | # endif | 133 | # endif |
134 | 134 | ||
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 1b8c073adb44..816c0fa12dc0 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile | |||
@@ -6,7 +6,6 @@ ccflags := -Werror | |||
6 | 6 | ||
7 | lib-y := bootstr_$(BITS).o | 7 | lib-y := bootstr_$(BITS).o |
8 | lib-$(CONFIG_SPARC32) += devmap.o | 8 | lib-$(CONFIG_SPARC32) += devmap.o |
9 | lib-y += devops_$(BITS).o | ||
10 | lib-y += init_$(BITS).o | 9 | lib-y += init_$(BITS).o |
11 | lib-$(CONFIG_SPARC32) += memory.o | 10 | lib-$(CONFIG_SPARC32) += memory.o |
12 | lib-y += misc_$(BITS).o | 11 | lib-y += misc_$(BITS).o |
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 5340264b78f5..48863108a44c 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c | |||
@@ -16,63 +16,26 @@ | |||
16 | 16 | ||
17 | extern void restore_current(void); | 17 | extern void restore_current(void); |
18 | 18 | ||
19 | /* Non blocking get character from console input device, returns -1 | ||
20 | * if no input was taken. This can be used for polling. | ||
21 | */ | ||
22 | int | ||
23 | prom_nbgetchar(void) | ||
24 | { | ||
25 | static char inc; | ||
26 | int i = -1; | ||
27 | unsigned long flags; | ||
28 | |||
29 | spin_lock_irqsave(&prom_lock, flags); | ||
30 | switch(prom_vers) { | ||
31 | case PROM_V0: | ||
32 | i = (*(romvec->pv_nbgetchar))(); | ||
33 | break; | ||
34 | case PROM_V2: | ||
35 | case PROM_V3: | ||
36 | if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) { | ||
37 | i = inc; | ||
38 | } else { | ||
39 | i = -1; | ||
40 | } | ||
41 | break; | ||
42 | default: | ||
43 | i = -1; | ||
44 | break; | ||
45 | }; | ||
46 | restore_current(); | ||
47 | spin_unlock_irqrestore(&prom_lock, flags); | ||
48 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | ||
49 | } | ||
50 | |||
51 | /* Non blocking put character to console device, returns -1 if | 19 | /* Non blocking put character to console device, returns -1 if |
52 | * unsuccessful. | 20 | * unsuccessful. |
53 | */ | 21 | */ |
54 | int | 22 | static int prom_nbputchar(const char *buf) |
55 | prom_nbputchar(char c) | ||
56 | { | 23 | { |
57 | static char outc; | ||
58 | unsigned long flags; | 24 | unsigned long flags; |
59 | int i = -1; | 25 | int i = -1; |
60 | 26 | ||
61 | spin_lock_irqsave(&prom_lock, flags); | 27 | spin_lock_irqsave(&prom_lock, flags); |
62 | switch(prom_vers) { | 28 | switch(prom_vers) { |
63 | case PROM_V0: | 29 | case PROM_V0: |
64 | i = (*(romvec->pv_nbputchar))(c); | 30 | i = (*(romvec->pv_nbputchar))(*buf); |
65 | break; | 31 | break; |
66 | case PROM_V2: | 32 | case PROM_V2: |
67 | case PROM_V3: | 33 | case PROM_V3: |
68 | outc = c; | 34 | if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, |
69 | if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1) | 35 | buf, 0x1) == 1) |
70 | i = 0; | 36 | i = 0; |
71 | else | ||
72 | i = -1; | ||
73 | break; | 37 | break; |
74 | default: | 38 | default: |
75 | i = -1; | ||
76 | break; | 39 | break; |
77 | }; | 40 | }; |
78 | restore_current(); | 41 | restore_current(); |
@@ -80,18 +43,14 @@ prom_nbputchar(char c) | |||
80 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | 43 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ |
81 | } | 44 | } |
82 | 45 | ||
83 | /* Blocking version of get character routine above. */ | 46 | void prom_console_write_buf(const char *buf, int len) |
84 | char | ||
85 | prom_getchar(void) | ||
86 | { | 47 | { |
87 | int character; | 48 | while (len) { |
88 | while((character = prom_nbgetchar()) == -1) ; | 49 | int n = prom_nbputchar(buf); |
89 | return (char) character; | 50 | if (n) |
51 | continue; | ||
52 | len--; | ||
53 | buf++; | ||
54 | } | ||
90 | } | 55 | } |
91 | 56 | ||
92 | /* Blocking version of put character routine above. */ | ||
93 | void | ||
94 | prom_putchar(char c) | ||
95 | { | ||
96 | while(prom_nbputchar(c) == -1) ; | ||
97 | } | ||
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 10322dc2f557..ed39e75828bd 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
@@ -15,85 +15,34 @@ | |||
15 | 15 | ||
16 | extern int prom_stdin, prom_stdout; | 16 | extern int prom_stdin, prom_stdout; |
17 | 17 | ||
18 | /* Non blocking get character from console input device, returns -1 | 18 | static int __prom_console_write_buf(const char *buf, int len) |
19 | * if no input was taken. This can be used for polling. | ||
20 | */ | ||
21 | inline int | ||
22 | prom_nbgetchar(void) | ||
23 | { | ||
24 | unsigned long args[7]; | ||
25 | char inc; | ||
26 | |||
27 | args[0] = (unsigned long) "read"; | ||
28 | args[1] = 3; | ||
29 | args[2] = 1; | ||
30 | args[3] = (unsigned int) prom_stdin; | ||
31 | args[4] = (unsigned long) &inc; | ||
32 | args[5] = 1; | ||
33 | args[6] = (unsigned long) -1; | ||
34 | |||
35 | p1275_cmd_direct(args); | ||
36 | |||
37 | if (args[6] == 1) | ||
38 | return inc; | ||
39 | return -1; | ||
40 | } | ||
41 | |||
42 | /* Non blocking put character to console device, returns -1 if | ||
43 | * unsuccessful. | ||
44 | */ | ||
45 | inline int | ||
46 | prom_nbputchar(char c) | ||
47 | { | 19 | { |
48 | unsigned long args[7]; | 20 | unsigned long args[7]; |
49 | char outc; | 21 | int ret; |
50 | |||
51 | outc = c; | ||
52 | 22 | ||
53 | args[0] = (unsigned long) "write"; | 23 | args[0] = (unsigned long) "write"; |
54 | args[1] = 3; | 24 | args[1] = 3; |
55 | args[2] = 1; | 25 | args[2] = 1; |
56 | args[3] = (unsigned int) prom_stdout; | 26 | args[3] = (unsigned int) prom_stdout; |
57 | args[4] = (unsigned long) &outc; | 27 | args[4] = (unsigned long) buf; |
58 | args[5] = 1; | 28 | args[5] = (unsigned int) len; |
59 | args[6] = (unsigned long) -1; | 29 | args[6] = (unsigned long) -1; |
60 | 30 | ||
61 | p1275_cmd_direct(args); | 31 | p1275_cmd_direct(args); |
62 | 32 | ||
63 | if (args[6] == 1) | 33 | ret = (int) args[6]; |
64 | return 0; | 34 | if (ret < 0) |
65 | else | ||
66 | return -1; | 35 | return -1; |
36 | return ret; | ||
67 | } | 37 | } |
68 | 38 | ||
69 | /* Blocking version of get character routine above. */ | 39 | void prom_console_write_buf(const char *buf, int len) |
70 | char | ||
71 | prom_getchar(void) | ||
72 | { | ||
73 | int character; | ||
74 | while((character = prom_nbgetchar()) == -1) ; | ||
75 | return (char) character; | ||
76 | } | ||
77 | |||
78 | /* Blocking version of put character routine above. */ | ||
79 | void | ||
80 | prom_putchar(char c) | ||
81 | { | 40 | { |
82 | prom_nbputchar(c); | 41 | while (len) { |
83 | } | 42 | int n = __prom_console_write_buf(buf, len); |
84 | 43 | if (n < 0) | |
85 | void | 44 | continue; |
86 | prom_puts(const char *s, int len) | 45 | len -= n; |
87 | { | 46 | buf += len; |
88 | unsigned long args[7]; | 47 | } |
89 | |||
90 | args[0] = (unsigned long) "write"; | ||
91 | args[1] = 3; | ||
92 | args[2] = 1; | ||
93 | args[3] = (unsigned int) prom_stdout; | ||
94 | args[4] = (unsigned long) s; | ||
95 | args[5] = len; | ||
96 | args[6] = (unsigned long) -1; | ||
97 | |||
98 | p1275_cmd_direct(args); | ||
99 | } | 48 | } |
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c deleted file mode 100644 index 9c5d4687242a..000000000000 --- a/arch/sparc/prom/devops_32.c +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | /* | ||
2 | * devops.c: Device operations using the PROM. | ||
3 | * | ||
4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
5 | */ | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/sched.h> | ||
9 | |||
10 | #include <asm/openprom.h> | ||
11 | #include <asm/oplib.h> | ||
12 | |||
13 | extern void restore_current(void); | ||
14 | |||
15 | /* Open the device described by the string 'dstr'. Returns the handle | ||
16 | * to that device used for subsequent operations on that device. | ||
17 | * Returns -1 on failure. | ||
18 | */ | ||
19 | int | ||
20 | prom_devopen(char *dstr) | ||
21 | { | ||
22 | int handle; | ||
23 | unsigned long flags; | ||
24 | spin_lock_irqsave(&prom_lock, flags); | ||
25 | switch(prom_vers) { | ||
26 | case PROM_V0: | ||
27 | handle = (*(romvec->pv_v0devops.v0_devopen))(dstr); | ||
28 | if(handle == 0) handle = -1; | ||
29 | break; | ||
30 | case PROM_V2: | ||
31 | case PROM_V3: | ||
32 | handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr); | ||
33 | break; | ||
34 | default: | ||
35 | handle = -1; | ||
36 | break; | ||
37 | }; | ||
38 | restore_current(); | ||
39 | spin_unlock_irqrestore(&prom_lock, flags); | ||
40 | |||
41 | return handle; | ||
42 | } | ||
43 | |||
44 | /* Close the device described by device handle 'dhandle'. */ | ||
45 | int | ||
46 | prom_devclose(int dhandle) | ||
47 | { | ||
48 | unsigned long flags; | ||
49 | spin_lock_irqsave(&prom_lock, flags); | ||
50 | switch(prom_vers) { | ||
51 | case PROM_V0: | ||
52 | (*(romvec->pv_v0devops.v0_devclose))(dhandle); | ||
53 | break; | ||
54 | case PROM_V2: | ||
55 | case PROM_V3: | ||
56 | (*(romvec->pv_v2devops.v2_dev_close))(dhandle); | ||
57 | break; | ||
58 | default: | ||
59 | break; | ||
60 | }; | ||
61 | restore_current(); | ||
62 | spin_unlock_irqrestore(&prom_lock, flags); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | /* Seek to specified location described by 'seekhi' and 'seeklo' | ||
67 | * for device 'dhandle'. | ||
68 | */ | ||
69 | void | ||
70 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | ||
71 | { | ||
72 | unsigned long flags; | ||
73 | spin_lock_irqsave(&prom_lock, flags); | ||
74 | switch(prom_vers) { | ||
75 | case PROM_V0: | ||
76 | (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo); | ||
77 | break; | ||
78 | case PROM_V2: | ||
79 | case PROM_V3: | ||
80 | (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo); | ||
81 | break; | ||
82 | default: | ||
83 | break; | ||
84 | }; | ||
85 | restore_current(); | ||
86 | spin_unlock_irqrestore(&prom_lock, flags); | ||
87 | } | ||
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c deleted file mode 100644 index a017119e7ef1..000000000000 --- a/arch/sparc/prom/devops_64.c +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | /* | ||
2 | * devops.c: Device operations using the PROM. | ||
3 | * | ||
4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
5 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
6 | */ | ||
7 | #include <linux/types.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/sched.h> | ||
10 | |||
11 | #include <asm/openprom.h> | ||
12 | #include <asm/oplib.h> | ||
13 | |||
14 | /* Open the device described by the string 'dstr'. Returns the handle | ||
15 | * to that device used for subsequent operations on that device. | ||
16 | * Returns 0 on failure. | ||
17 | */ | ||
18 | int | ||
19 | prom_devopen(const char *dstr) | ||
20 | { | ||
21 | unsigned long args[5]; | ||
22 | |||
23 | args[0] = (unsigned long) "open"; | ||
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned long) dstr; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
32 | } | ||
33 | |||
34 | /* Close the device described by device handle 'dhandle'. */ | ||
35 | int | ||
36 | prom_devclose(int dhandle) | ||
37 | { | ||
38 | unsigned long args[4]; | ||
39 | |||
40 | args[0] = (unsigned long) "close"; | ||
41 | args[1] = 1; | ||
42 | args[2] = 0; | ||
43 | args[3] = (unsigned int) dhandle; | ||
44 | |||
45 | p1275_cmd_direct(args); | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | /* Seek to specified location described by 'seekhi' and 'seeklo' | ||
51 | * for device 'dhandle'. | ||
52 | */ | ||
53 | void | ||
54 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | ||
55 | { | ||
56 | unsigned long args[7]; | ||
57 | |||
58 | args[0] = (unsigned long) "seek"; | ||
59 | args[1] = 3; | ||
60 | args[2] = 1; | ||
61 | args[3] = (unsigned int) dhandle; | ||
62 | args[4] = seekhi; | ||
63 | args[5] = seeklo; | ||
64 | args[6] = (unsigned long) -1; | ||
65 | |||
66 | p1275_cmd_direct(args); | ||
67 | } | ||
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index d24bc44e361e..e4f31d4d3715 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
19 | #include <asm/ldc.h> | 19 | #include <asm/ldc.h> |
20 | 20 | ||
21 | int prom_service_exists(const char *service_name) | 21 | static int prom_service_exists(const char *service_name) |
22 | { | 22 | { |
23 | unsigned long args[5]; | 23 | unsigned long args[5]; |
24 | 24 | ||
@@ -150,20 +150,6 @@ void prom_halt_power_off(void) | |||
150 | prom_halt(); | 150 | prom_halt(); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* Set prom sync handler to call function 'funcp'. */ | ||
154 | void prom_setcallback(callback_func_t funcp) | ||
155 | { | ||
156 | unsigned long args[5]; | ||
157 | if (!funcp) | ||
158 | return; | ||
159 | args[0] = (unsigned long) "set-callback"; | ||
160 | args[1] = 1; | ||
161 | args[2] = 1; | ||
162 | args[3] = (unsigned long) funcp; | ||
163 | args[4] = (unsigned long) -1; | ||
164 | p1275_cmd_direct(args); | ||
165 | } | ||
166 | |||
167 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the | 153 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the |
168 | * format type. 'num_bytes' is the number of bytes that your idbuf | 154 | * format type. 'num_bytes' is the number of bytes that your idbuf |
169 | * has space for. Returns 0xff on error. | 155 | * has space for. Returns 0xff on error. |
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index ca869266b9f3..d9682f06b3b0 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c | |||
@@ -15,22 +15,45 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
18 | #include <linux/spinlock.h> | ||
18 | 19 | ||
19 | #include <asm/openprom.h> | 20 | #include <asm/openprom.h> |
20 | #include <asm/oplib.h> | 21 | #include <asm/oplib.h> |
21 | 22 | ||
23 | #define CONSOLE_WRITE_BUF_SIZE 1024 | ||
24 | |||
22 | static char ppbuf[1024]; | 25 | static char ppbuf[1024]; |
26 | static char console_write_buf[CONSOLE_WRITE_BUF_SIZE]; | ||
27 | static DEFINE_RAW_SPINLOCK(console_write_lock); | ||
23 | 28 | ||
24 | void notrace prom_write(const char *buf, unsigned int n) | 29 | void notrace prom_write(const char *buf, unsigned int n) |
25 | { | 30 | { |
26 | char ch; | 31 | unsigned int dest_len; |
32 | unsigned long flags; | ||
33 | char *dest; | ||
34 | |||
35 | dest = console_write_buf; | ||
36 | raw_spin_lock_irqsave(&console_write_lock, flags); | ||
27 | 37 | ||
28 | while (n != 0) { | 38 | dest_len = 0; |
29 | --n; | 39 | while (n-- != 0) { |
30 | if ((ch = *buf++) == '\n') | 40 | char ch = *buf++; |
31 | prom_putchar('\r'); | 41 | if (ch == '\n') { |
32 | prom_putchar(ch); | 42 | *dest++ = '\r'; |
43 | dest_len++; | ||
44 | } | ||
45 | *dest++ = ch; | ||
46 | dest_len++; | ||
47 | if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) { | ||
48 | prom_console_write_buf(console_write_buf, dest_len); | ||
49 | dest = console_write_buf; | ||
50 | dest_len = 0; | ||
51 | } | ||
33 | } | 52 | } |
53 | if (dest_len) | ||
54 | prom_console_write_buf(console_write_buf, dest_len); | ||
55 | |||
56 | raw_spin_unlock_irqrestore(&console_write_lock, flags); | ||
34 | } | 57 | } |
35 | 58 | ||
36 | void notrace prom_printf(const char *fmt, ...) | 59 | void notrace prom_printf(const char *fmt, ...) |
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c index 63e08e149774..535e2e69ac1d 100644 --- a/arch/sparc/prom/tree_32.c +++ b/arch/sparc/prom/tree_32.c | |||
@@ -342,19 +342,3 @@ phandle prom_inst2pkg(int inst) | |||
342 | if (node == -1) return 0; | 342 | if (node == -1) return 0; |
343 | return node; | 343 | return node; |
344 | } | 344 | } |
345 | |||
346 | /* Return 'node' assigned to a particular prom 'path' | ||
347 | * FIXME: Should work for v0 as well | ||
348 | */ | ||
349 | phandle prom_pathtoinode(char *path) | ||
350 | { | ||
351 | phandle node; | ||
352 | int inst; | ||
353 | |||
354 | inst = prom_devopen (path); | ||
355 | if (inst == -1) return 0; | ||
356 | node = prom_inst2pkg (inst); | ||
357 | prom_devclose (inst); | ||
358 | if (node == -1) return 0; | ||
359 | return node; | ||
360 | } | ||
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 691be68932f8..d93660048376 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c | |||
@@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst) | |||
374 | return node; | 374 | return node; |
375 | } | 375 | } |
376 | 376 | ||
377 | /* Return 'node' assigned to a particular prom 'path' | ||
378 | * FIXME: Should work for v0 as well | ||
379 | */ | ||
380 | phandle prom_pathtoinode(const char *path) | ||
381 | { | ||
382 | phandle node; | ||
383 | int inst; | ||
384 | |||
385 | inst = prom_devopen (path); | ||
386 | if (inst == 0) | ||
387 | return 0; | ||
388 | node = prom_inst2pkg(inst); | ||
389 | prom_devclose(inst); | ||
390 | if (node == -1) | ||
391 | return 0; | ||
392 | return node; | ||
393 | } | ||
394 | |||
395 | int prom_ihandle2path(int handle, char *buffer, int bufsize) | 377 | int prom_ihandle2path(int handle, char *buffer, int bufsize) |
396 | { | 378 | { |
397 | unsigned long args[7]; | 379 | unsigned long args[7]; |
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index cbcc8d8ea93a..7a6e68e4f748 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * by the Free Software Foundation. | 10 | * by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/err.h> | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index 7f7e577a0e39..31d84acc1512 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h | |||
@@ -11,6 +11,7 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); | |||
11 | void pvclock_read_wallclock(struct pvclock_wall_clock *wall, | 11 | void pvclock_read_wallclock(struct pvclock_wall_clock *wall, |
12 | struct pvclock_vcpu_time_info *vcpu, | 12 | struct pvclock_vcpu_time_info *vcpu, |
13 | struct timespec *ts); | 13 | struct timespec *ts); |
14 | void pvclock_resume(void); | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, | 17 | * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, |
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 008b91eefa18..42eb3300dfc6 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c | |||
@@ -83,6 +83,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) | |||
83 | 83 | ||
84 | static atomic64_t last_value = ATOMIC64_INIT(0); | 84 | static atomic64_t last_value = ATOMIC64_INIT(0); |
85 | 85 | ||
86 | void pvclock_resume(void) | ||
87 | { | ||
88 | atomic64_set(&last_value, 0); | ||
89 | } | ||
90 | |||
86 | cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) | 91 | cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) |
87 | { | 92 | { |
88 | struct pvclock_shadow_time shadow; | 93 | struct pvclock_shadow_time shadow; |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index b2bb5aa3b054..5da5e53fb94c 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -426,6 +426,8 @@ void xen_timer_resume(void) | |||
426 | { | 426 | { |
427 | int cpu; | 427 | int cpu; |
428 | 428 | ||
429 | pvclock_resume(); | ||
430 | |||
429 | if (xen_clockevent != &xen_vcpuop_clockevent) | 431 | if (xen_clockevent != &xen_vcpuop_clockevent) |
430 | return; | 432 | return; |
431 | 433 | ||