aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/mn10300/Kconfig119
-rw-r--r--arch/mn10300/Makefile6
-rw-r--r--arch/mn10300/boot/compressed/head.S20
-rw-r--r--arch/mn10300/include/asm/exceptions.h2
-rw-r--r--arch/mn10300/include/asm/frame.inc36
-rw-r--r--arch/mn10300/include/asm/hardirq.h2
-rw-r--r--arch/mn10300/include/asm/intctl-regs.h37
-rw-r--r--arch/mn10300/include/asm/irq.h4
-rw-r--r--arch/mn10300/include/asm/irqflags.h26
-rw-r--r--arch/mn10300/include/asm/pgtable.h19
-rw-r--r--arch/mn10300/include/asm/processor.h47
-rw-r--r--arch/mn10300/include/asm/ptrace.h15
-rw-r--r--arch/mn10300/include/asm/reset-regs.h2
-rw-r--r--arch/mn10300/include/asm/rtc.h11
-rw-r--r--arch/mn10300/include/asm/rwlock.h125
-rw-r--r--arch/mn10300/include/asm/serial-regs.h51
-rw-r--r--arch/mn10300/include/asm/serial.h8
-rw-r--r--arch/mn10300/include/asm/smp.h102
-rw-r--r--arch/mn10300/include/asm/spinlock.h179
-rw-r--r--arch/mn10300/include/asm/spinlock_types.h20
-rw-r--r--arch/mn10300/include/asm/system.h11
-rw-r--r--arch/mn10300/include/asm/timer-regs.h191
-rw-r--r--arch/mn10300/include/asm/timex.h3
-rw-r--r--arch/mn10300/include/asm/uaccess.h2
-rw-r--r--arch/mn10300/kernel/Makefile3
-rw-r--r--arch/mn10300/kernel/asm-offsets.c2
-rw-r--r--arch/mn10300/kernel/entry.S113
-rw-r--r--arch/mn10300/kernel/gdb-io-serial-low.S5
-rw-r--r--arch/mn10300/kernel/gdb-io-serial.c37
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c24
-rw-r--r--arch/mn10300/kernel/gdb-stub.c17
-rw-r--r--arch/mn10300/kernel/head.S196
-rw-r--r--arch/mn10300/kernel/internal.h12
-rw-r--r--arch/mn10300/kernel/irq.c266
-rw-r--r--arch/mn10300/kernel/mn10300-serial-low.S6
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c210
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog-low.S9
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog.c100
-rw-r--r--arch/mn10300/kernel/process.c41
-rw-r--r--arch/mn10300/kernel/profile.c2
-rw-r--r--arch/mn10300/kernel/rtc.c41
-rw-r--r--arch/mn10300/kernel/setup.c75
-rw-r--r--arch/mn10300/kernel/smp-low.S97
-rw-r--r--arch/mn10300/kernel/smp.c1141
-rw-r--r--arch/mn10300/kernel/switch_to.S17
-rw-r--r--arch/mn10300/kernel/time.c32
-rw-r--r--arch/mn10300/kernel/traps.c18
-rw-r--r--arch/mn10300/lib/delay.c8
-rw-r--r--arch/mn10300/mm/fault.c12
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/clock.h2
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h29
-rw-r--r--arch/mn10300/proc-mn103e010/proc-init.c35
-rw-r--r--arch/mn10300/proc-mn2ws0050/Makefile5
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/cache.h48
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/clock.h20
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h103
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h29
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/irq.h49
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h120
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/proc.h18
-rw-r--r--arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h51
-rw-r--r--arch/mn10300/proc-mn2ws0050/proc-init.c134
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/clock.h25
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/serial.h5
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/timex.h64
-rw-r--r--arch/mn10300/unit-asb2303/unit-init.c10
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/clock.h25
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/serial.h5
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/timex.h66
-rw-r--r--arch/mn10300/unit-asb2305/pci.c2
-rw-r--r--arch/mn10300/unit-asb2305/unit-init.c6
-rw-r--r--arch/mn10300/unit-asb2364/Makefile10
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/clock.h29
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/fpga-regs.h50
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/leds.h54
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/serial.h151
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/timex.h125
-rw-r--r--arch/mn10300/unit-asb2364/leds.c98
-rw-r--r--arch/mn10300/unit-asb2364/unit-init.c85
80 files changed, 4495 insertions, 482 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index debde0128cd0..1e6b6bdf6340 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4448,7 +4448,7 @@ L: platform-driver-x86@vger.kernel.org
4448S: Maintained 4448S: Maintained
4449F: drivers/platform/x86/panasonic-laptop.c 4449F: drivers/platform/x86/panasonic-laptop.c
4450 4450
4451PANASONIC MN10300/AM33 PORT 4451PANASONIC MN10300/AM33/AM34 PORT
4452M: David Howells <dhowells@redhat.com> 4452M: David Howells <dhowells@redhat.com>
4453M: Koichi Yasutake <yasutake.koichi@jp.panasonic.com> 4453M: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
4454L: linux-am33-list@redhat.com (moderated for non-subscribers) 4454L: linux-am33-list@redhat.com (moderated for non-subscribers)
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index a0a16e6e4a4e..81e27816aaf8 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -48,7 +48,7 @@ config GENERIC_CALIBRATE_DELAY
48 def_bool y 48 def_bool y
49 49
50config GENERIC_CMOS_UPDATE 50config GENERIC_CMOS_UPDATE
51 def_bool y 51 def_bool n
52 52
53config GENERIC_FIND_NEXT_BIT 53config GENERIC_FIND_NEXT_BIT
54 def_bool y 54 def_bool y
@@ -72,10 +72,6 @@ config GENERIC_HARDIRQS
72config HOTPLUG_CPU 72config HOTPLUG_CPU
73 def_bool n 73 def_bool n
74 74
75config HZ
76 int
77 default 1000
78
79mainmenu "Matsushita MN10300/AM33 Kernel Configuration" 75mainmenu "Matsushita MN10300/AM33 Kernel Configuration"
80 76
81source "init/Kconfig" 77source "init/Kconfig"
@@ -98,6 +94,9 @@ config MN10300_UNIT_ASB2303
98config MN10300_UNIT_ASB2305 94config MN10300_UNIT_ASB2305
99 bool "ASB2305" 95 bool "ASB2305"
100 96
97config MN10300_UNIT_ASB2364
98 bool "ASB2364"
99
101endchoice 100endchoice
102 101
103choice 102choice
@@ -115,17 +114,13 @@ config MN10300_PROC_MN103E010
115 select MN10300_PROC_HAS_TTYSM1 114 select MN10300_PROC_HAS_TTYSM1
116 select MN10300_PROC_HAS_TTYSM2 115 select MN10300_PROC_HAS_TTYSM2
117 116
118endchoice 117config MN10300_PROC_MN2WS0050
119 118 bool "MN2WS0050"
120choice 119 depends on MN10300_UNIT_ASB2364
121 prompt "Processor core support" 120 select AM34_2
122 default MN10300_CPU_AM33V2 121 select MN10300_PROC_HAS_TTYSM0
123 help 122 select MN10300_PROC_HAS_TTYSM1
124 This option specifies the processor core for which the kernel will be 123 select MN10300_PROC_HAS_TTYSM2
125 compiled. It affects the instruction set used.
126
127config MN10300_CPU_AM33V2
128 bool "AM33v2"
129 124
130endchoice 125endchoice
131 126
@@ -138,7 +133,7 @@ config MN10300_HAS_ATOMIC_OPS_UNIT
138config FPU 133config FPU
139 bool "FPU present" 134 bool "FPU present"
140 default y 135 default y
141 depends on MN10300_PROC_MN103E010 136 depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050
142 137
143config LAZY_SAVE_FPU 138config LAZY_SAVE_FPU
144 bool "Save FPU state lazily" 139 bool "Save FPU state lazily"
@@ -179,24 +174,55 @@ config KERNEL_TEXT_ADDRESS
179 174
180config KERNEL_ZIMAGE_BASE_ADDRESS 175config KERNEL_ZIMAGE_BASE_ADDRESS
181 hex "Base address of compressed vmlinux image" 176 hex "Base address of compressed vmlinux image"
182 default "0x90700000" 177 default "0x50700000"
178
179config BOOT_STACK_OFFSET
180 hex
181 default "0xF00" if SMP
182 default "0xFF0" if !SMP
183 183
184config BOOT_STACK_SIZE
185 hex
186 depends on SMP
187 default "0x100"
184endmenu 188endmenu
185 189
186config PREEMPT 190config SMP
187 bool "Preemptible Kernel" 191 bool "Symmetric multi-processing support"
188 help 192 default y
189 This option reduces the latency of the kernel when reacting to 193 depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050
190 real-time or interactive events by allowing a low priority process to 194 ---help---
191 be preempted even if it is in kernel mode executing a system call. 195 This enables support for systems with more than one CPU. If you have
192 This allows applications to run more reliably even when the system is 196 a system with only one CPU, like most personal computers, say N. If
193 under load. 197 you have a system with more than one CPU, say Y.
198
199 If you say N here, the kernel will run on single and multiprocessor
200 machines, but will use only one CPU of a multiprocessor machine. If
201 you say Y here, the kernel will run on many, but not all,
202 singleprocessor machines. On a singleprocessor machine, the kernel
203 will run faster if you say N here.
204
205 See also <file:Documentation/i386/IO-APIC.txt>,
206 <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
207 <http://www.tldp.org/docs.html#howto>.
194 208
195 Say Y here if you are building a kernel for a desktop, embedded 209 If you don't know what to do here, say N.
196 or real-time system. Say N if you are unsure. 210
211config NR_CPUS
212 int
213 depends on SMP
214 default "2"
215
216config USE_GENERIC_SMP_HELPERS
217 bool
218 depends on SMP
219 default y
220
221source "kernel/Kconfig.preempt"
197 222
198config MN10300_CURRENT_IN_E2 223config MN10300_CURRENT_IN_E2
199 bool "Hold current task address in E2 register" 224 bool "Hold current task address in E2 register"
225 depends on !SMP
200 default y 226 default y
201 help 227 help
202 This option removes the E2/R2 register from the set available to gcc 228 This option removes the E2/R2 register from the set available to gcc
@@ -218,12 +244,14 @@ config MN10300_USING_JTAG
218 suppresses the use of certain hardware debugging features, such as 244 suppresses the use of certain hardware debugging features, such as
219 single-stepping, which are taken over completely by the JTAG unit. 245 single-stepping, which are taken over completely by the JTAG unit.
220 246
247source "kernel/Kconfig.hz"
248
221config MN10300_RTC 249config MN10300_RTC
222 bool "Using MN10300 RTC" 250 bool "Using MN10300 RTC"
223 depends on MN10300_PROC_MN103E010 251 depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050
252 select GENERIC_CMOS_UPDATE
224 default n 253 default n
225 help 254 help
226
227 This option enables support for the RTC, thus enabling time to be 255 This option enables support for the RTC, thus enabling time to be
228 tracked, even when system is powered down. This is available on-chip 256 tracked, even when system is powered down. This is available on-chip
229 on the MN103E010. 257 on the MN103E010.
@@ -315,14 +343,23 @@ config MN10300_TTYSM1
315 343
316choice 344choice
317 prompt "Select the timer to supply the clock for SIF1" 345 prompt "Select the timer to supply the clock for SIF1"
318 default MN10300_TTYSM0_TIMER9 346 default MN10300_TTYSM1_TIMER12 \
347 if !(AM33_2 || AM33_3)
348 default MN10300_TTYSM1_TIMER9 \
349 if AM33_2 || AM33_3
319 depends on MN10300_TTYSM1 350 depends on MN10300_TTYSM1
320 351
352config MN10300_TTYSM1_TIMER12
353 bool "Use timer 12 (16-bit)"
354 depends on !(AM33_2 || AM33_3)
355
321config MN10300_TTYSM1_TIMER9 356config MN10300_TTYSM1_TIMER9
322 bool "Use timer 9 (16-bit)" 357 bool "Use timer 9 (16-bit)"
358 depends on AM33_2 || AM33_3
323 359
324config MN10300_TTYSM1_TIMER3 360config MN10300_TTYSM1_TIMER3
325 bool "Use timer 3 (8-bit)" 361 bool "Use timer 3 (8-bit)"
362 depends on AM33_2 || AM33_3
326 363
327endchoice 364endchoice
328 365
@@ -337,17 +374,33 @@ config MN10300_TTYSM2
337 374
338choice 375choice
339 prompt "Select the timer to supply the clock for SIF2" 376 prompt "Select the timer to supply the clock for SIF2"
340 default MN10300_TTYSM0_TIMER10 377 default MN10300_TTYSM2_TIMER3 \
378 if !(AM33_2 || AM33_3)
379 default MN10300_TTYSM2_TIMER10 \
380 if AM33_2 || AM33_3
341 depends on MN10300_TTYSM2 381 depends on MN10300_TTYSM2
342 382
383config MN10300_TTYSM2_TIMER9
384 bool "Use timer 9 (16-bit)"
385 depends on !(AM33_2 || AM33_3)
386
387config MN10300_TTYSM2_TIMER1
388 bool "Use timer 1 (8-bit)"
389 depends on !(AM33_2 || AM33_3)
390
391config MN10300_TTYSM2_TIMER3
392 bool "Use timer 3 (8-bit)"
393 depends on !(AM33_2 || AM33_3)
394
343config MN10300_TTYSM2_TIMER10 395config MN10300_TTYSM2_TIMER10
344 bool "Use timer 10 (16-bit)" 396 bool "Use timer 10 (16-bit)"
397 depends on AM33_2 || AM33_3
345 398
346endchoice 399endchoice
347 400
348config MN10300_TTYSM2_CTS 401config MN10300_TTYSM2_CTS
349 bool "Enable the use of the CTS line /dev/ttySM2" 402 bool "Enable the use of the CTS line /dev/ttySM2"
350 depends on MN10300_TTYSM2 403 depends on MN10300_TTYSM2 && AM33_2
351 404
352endmenu 405endmenu
353 406
diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile
index ac5c6bdb2f05..7120282bf0d8 100644
--- a/arch/mn10300/Makefile
+++ b/arch/mn10300/Makefile
@@ -36,6 +36,9 @@ endif
36ifeq ($(CONFIG_MN10300_PROC_MN103E010),y) 36ifeq ($(CONFIG_MN10300_PROC_MN103E010),y)
37PROCESSOR := mn103e010 37PROCESSOR := mn103e010
38endif 38endif
39ifeq ($(CONFIG_MN10300_PROC_MN2WS0050),y)
40PROCESSOR := mn2ws0050
41endif
39 42
40ifeq ($(CONFIG_MN10300_UNIT_ASB2303),y) 43ifeq ($(CONFIG_MN10300_UNIT_ASB2303),y)
41UNIT := asb2303 44UNIT := asb2303
@@ -43,6 +46,9 @@ endif
43ifeq ($(CONFIG_MN10300_UNIT_ASB2305),y) 46ifeq ($(CONFIG_MN10300_UNIT_ASB2305),y)
44UNIT := asb2305 47UNIT := asb2305
45endif 48endif
49ifeq ($(CONFIG_MN10300_UNIT_ASB2364),y)
50UNIT := asb2364
51endif
46 52
47 53
48head-y := arch/mn10300/kernel/head.o arch/mn10300/kernel/init_task.o 54head-y := arch/mn10300/kernel/head.o arch/mn10300/kernel/init_task.o
diff --git a/arch/mn10300/boot/compressed/head.S b/arch/mn10300/boot/compressed/head.S
index 4ef608a62416..7b50345b9e84 100644
--- a/arch/mn10300/boot/compressed/head.S
+++ b/arch/mn10300/boot/compressed/head.S
@@ -15,10 +15,28 @@
15#include <linux/linkage.h> 15#include <linux/linkage.h>
16#include <asm/cpu-regs.h> 16#include <asm/cpu-regs.h>
17#include <asm/cache.h> 17#include <asm/cache.h>
18#ifdef CONFIG_SMP
19#include <proc/smp-regs.h>
20#endif
18 21
19 .globl startup_32 22 .globl startup_32
20startup_32: 23startup_32:
21 # first save off parameters from bootloader 24#ifdef CONFIG_SMP
25 #
26 # Secondary CPUs jump directly to the kernel entry point
27 #
28 # Must save primary CPU's D0-D2 registers as they hold boot parameters
29 #
30 mov (CPUID), d3
31 and CPUID_MASK,d3
32 beq startup_primary
33 mov CONFIG_KERNEL_TEXT_ADDRESS,a0
34 jmp (a0)
35
36startup_primary:
37#endif /* CONFIG_SMP */
38
39 # first save parameters from bootloader
22 mov param_save_area,a0 40 mov param_save_area,a0
23 mov d0,(a0) 41 mov d0,(a0)
24 mov d1,(4,a0) 42 mov d1,(4,a0)
diff --git a/arch/mn10300/include/asm/exceptions.h b/arch/mn10300/include/asm/exceptions.h
index 7d8080bc6590..ca3e20508c77 100644
--- a/arch/mn10300/include/asm/exceptions.h
+++ b/arch/mn10300/include/asm/exceptions.h
@@ -114,6 +114,8 @@ extern void die(const char *, struct pt_regs *, enum exception_code)
114 114
115extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code); 115extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code);
116 116
117#define NUM2EXCEP_IRQ_LEVEL(num) (EXCEP_IRQ_LEVEL0 + (num) * 8)
118
117#endif /* __ASSEMBLY__ */ 119#endif /* __ASSEMBLY__ */
118 120
119#endif /* _ASM_EXCEPTIONS_H */ 121#endif /* _ASM_EXCEPTIONS_H */
diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc
index 5b1949bdf039..406060e5e1c0 100644
--- a/arch/mn10300/include/asm/frame.inc
+++ b/arch/mn10300/include/asm/frame.inc
@@ -18,6 +18,9 @@
18#ifndef __ASM_OFFSETS_H__ 18#ifndef __ASM_OFFSETS_H__
19#include <asm/asm-offsets.h> 19#include <asm/asm-offsets.h>
20#endif 20#endif
21#ifdef CONFIG_SMP
22#include <proc/smp-regs.h>
23#endif
21 24
22#define pi break 25#define pi break
23 26
@@ -37,9 +40,25 @@
37 movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp) 40 movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp)
38 mov sp,fp # FRAME pointer in A3 41 mov sp,fp # FRAME pointer in A3
39 add -12,sp # allow for calls to be made 42 add -12,sp # allow for calls to be made
43#ifdef CONFIG_SMP
44#ifdef CONFIG_PREEMPT /* FIXME */
45 mov epsw,d2
46 and ~EPSW_IE,epsw
47#endif
48 mov (CPUID),a0
49 add a0,a0
50 add a0,a0
51 mov (___frame,a0),a1
52 mov a1,(REG_NEXT,fp)
53 mov fp,(___frame,a0)
54#ifdef CONFIG_PREEMPT /* FIXME */
55 mov d2,epsw
56#endif
57#else /* CONFIG_SMP */
40 mov (__frame),a1 58 mov (__frame),a1
41 mov a1,(REG_NEXT,fp) 59 mov a1,(REG_NEXT,fp)
42 mov fp,(__frame) 60 mov fp,(__frame)
61#endif /* CONFIG_SMP */
43 62
44 and ~EPSW_FE,epsw # disable the FPU inside the kernel 63 and ~EPSW_FE,epsw # disable the FPU inside the kernel
45 64
@@ -57,10 +76,27 @@
57.macro RESTORE_ALL 76.macro RESTORE_ALL
58 # peel back the stack to the calling frame 77 # peel back the stack to the calling frame
59 # - this permits execve() to discard extra frames due to kernel syscalls 78 # - this permits execve() to discard extra frames due to kernel syscalls
79#ifdef CONFIG_SMP
80#ifdef CONFIG_PREEMPT /* FIXME */
81 mov epsw,d2
82 and ~EPSW_IE,epsw
83#endif
84 mov (CPUID),a0
85 add a0,a0
86 add a0,a0
87 mov (___frame,a0),fp
88 mov fp,sp
89 mov (REG_NEXT,fp),d0 # userspace has regs->next == 0
90 mov d0,(___frame,a0)
91#ifdef CONFIG_PREEMPT /* FIXME */
92 mov d2,epsw
93#endif
94#else /* CONFIG_SMP */
60 mov (__frame),fp 95 mov (__frame),fp
61 mov fp,sp 96 mov fp,sp
62 mov (REG_NEXT,fp),d0 # userspace has regs->next == 0 97 mov (REG_NEXT,fp),d0 # userspace has regs->next == 0
63 mov d0,(__frame) 98 mov d0,(__frame)
99#endif /* CONFIG_SMP */
64 100
65#ifndef CONFIG_MN10300_USING_JTAG 101#ifndef CONFIG_MN10300_USING_JTAG
66 mov (REG_EPSW,fp),d0 102 mov (REG_EPSW,fp),d0
diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h
index 7bd9b7cc2451..0000d650b55f 100644
--- a/arch/mn10300/include/asm/hardirq.h
+++ b/arch/mn10300/include/asm/hardirq.h
@@ -19,8 +19,10 @@
19/* assembly code in softirq.h is sensitive to the offsets of these fields */ 19/* assembly code in softirq.h is sensitive to the offsets of these fields */
20typedef struct { 20typedef struct {
21 unsigned int __softirq_pending; 21 unsigned int __softirq_pending;
22#ifdef CONFIG_MN10300_WD_TIMER
22 unsigned int __nmi_count; /* arch dependent */ 23 unsigned int __nmi_count; /* arch dependent */
23 unsigned int __irq_count; /* arch dependent */ 24 unsigned int __irq_count; /* arch dependent */
25#endif
24} ____cacheline_aligned irq_cpustat_t; 26} ____cacheline_aligned irq_cpustat_t;
25 27
26#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 28#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/arch/mn10300/include/asm/intctl-regs.h b/arch/mn10300/include/asm/intctl-regs.h
index ba544c796c5a..585b708c2bc0 100644
--- a/arch/mn10300/include/asm/intctl-regs.h
+++ b/arch/mn10300/include/asm/intctl-regs.h
@@ -15,24 +15,19 @@
15 15
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18/* interrupt controller registers */ 18/*
19#define GxICR(X) __SYSREG(0xd4000000 + (X) * 4, u16) /* group irq ctrl regs */ 19 * Interrupt controller registers
20 20 * - Registers 64-191 are at addresses offset from the main array
21#define IAGR __SYSREG(0xd4000100, u16) /* intr acceptance group reg */ 21 */
22#define IAGR_GN 0x00fc /* group number register 22#define GxICR(X) \
23 * (documentation _has_ to be wrong) 23 __SYSREG(0xd4000000 + (X) * 4 + \
24 */ 24 (((X) >= 64) && ((X) < 192)) * 0xf00, u16)
25 25
26#define EXTMD __SYSREG(0xd4000200, u16) /* external pin intr spec reg */ 26#define GxICR_u8(X) \
27#define GET_XIRQ_TRIGGER(X) ((EXTMD >> ((X) * 2)) & 3) 27 __SYSREG(0xd4000000 + (X) * 4 + \
28 (((X) >= 64) && ((X) < 192)) * 0xf00, u8)
28 29
29#define SET_XIRQ_TRIGGER(X,Y) \ 30#include <proc/intctl-regs.h>
30do { \
31 u16 x = EXTMD; \
32 x &= ~(3 << ((X) * 2)); \
33 x |= ((Y) & 3) << ((X) * 2); \
34 EXTMD = x; \
35} while (0)
36 31
37#define XIRQ_TRIGGER_LOWLEVEL 0 32#define XIRQ_TRIGGER_LOWLEVEL 0
38#define XIRQ_TRIGGER_HILEVEL 1 33#define XIRQ_TRIGGER_HILEVEL 1
@@ -59,10 +54,18 @@ do { \
59#define GxICR_LEVEL_5 0x5000 /* - level 5 */ 54#define GxICR_LEVEL_5 0x5000 /* - level 5 */
60#define GxICR_LEVEL_6 0x6000 /* - level 6 */ 55#define GxICR_LEVEL_6 0x6000 /* - level 6 */
61#define GxICR_LEVEL_SHIFT 12 56#define GxICR_LEVEL_SHIFT 12
57#define GxICR_NMI 0x8000 /* nmi request flag */
58
59#define NUM2GxICR_LEVEL(num) ((num) << GxICR_LEVEL_SHIFT)
62 60
63#ifndef __ASSEMBLY__ 61#ifndef __ASSEMBLY__
64extern void set_intr_level(int irq, u16 level); 62extern void set_intr_level(int irq, u16 level);
65extern void set_intr_postackable(int irq); 63extern void mn10300_intc_set_level(unsigned int irq, unsigned int level);
64extern void mn10300_intc_clear(unsigned int irq);
65extern void mn10300_intc_set(unsigned int irq);
66extern void mn10300_intc_enable(unsigned int irq);
67extern void mn10300_intc_disable(unsigned int irq);
68extern void mn10300_set_lateack_irq_type(int irq);
66#endif 69#endif
67 70
68/* external interrupts */ 71/* external interrupts */
diff --git a/arch/mn10300/include/asm/irq.h b/arch/mn10300/include/asm/irq.h
index 25c045d16d1c..b7b8e175b167 100644
--- a/arch/mn10300/include/asm/irq.h
+++ b/arch/mn10300/include/asm/irq.h
@@ -22,7 +22,11 @@
22#define NO_IRQ INT_MAX 22#define NO_IRQ INT_MAX
23 23
24/* hardware irq numbers */ 24/* hardware irq numbers */
25#ifdef CONFIG_SMP
26#define NR_IRQS GxICR_NUM_EXT_IRQS
27#else
25#define NR_IRQS GxICR_NUM_IRQS 28#define NR_IRQS GxICR_NUM_IRQS
29#endif
26 30
27/* external hardware irq numbers */ 31/* external hardware irq numbers */
28#define NR_XIRQS GxICR_NUM_XIRQS 32#define NR_XIRQS GxICR_NUM_XIRQS
diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h
index b3ab2071354d..7a7ae12c7119 100644
--- a/arch/mn10300/include/asm/irqflags.h
+++ b/arch/mn10300/include/asm/irqflags.h
@@ -13,6 +13,9 @@
13#define _ASM_IRQFLAGS_H 13#define _ASM_IRQFLAGS_H
14 14
15#include <asm/cpu-regs.h> 15#include <asm/cpu-regs.h>
16#ifndef __ASSEMBLY__
17#include <linux/smp.h>
18#endif
16 19
17/* 20/*
18 * interrupt control 21 * interrupt control
@@ -60,11 +63,12 @@ static inline unsigned long arch_local_irq_save(void)
60/* 63/*
61 * we make sure arch_irq_enable() doesn't cause priority inversion 64 * we make sure arch_irq_enable() doesn't cause priority inversion
62 */ 65 */
63extern unsigned long __mn10300_irq_enabled_epsw; 66extern unsigned long __mn10300_irq_enabled_epsw[];
64 67
65static inline void arch_local_irq_enable(void) 68static inline void arch_local_irq_enable(void)
66{ 69{
67 unsigned long tmp; 70 unsigned long tmp;
71 int cpu = raw_smp_processor_id();
68 72
69 asm volatile( 73 asm volatile(
70 " mov epsw,%0 \n" 74 " mov epsw,%0 \n"
@@ -72,8 +76,8 @@ static inline void arch_local_irq_enable(void)
72 " or %2,%0 \n" 76 " or %2,%0 \n"
73 " mov %0,epsw \n" 77 " mov %0,epsw \n"
74 : "=&d"(tmp) 78 : "=&d"(tmp)
75 : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw) 79 : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw[cpu])
76 : "memory"); 80 : "memory", "cc");
77} 81}
78 82
79static inline void arch_local_irq_restore(unsigned long flags) 83static inline void arch_local_irq_restore(unsigned long flags)
@@ -105,6 +109,9 @@ static inline bool arch_irqs_disabled(void)
105 */ 109 */
106static inline void arch_safe_halt(void) 110static inline void arch_safe_halt(void)
107{ 111{
112#ifdef CONFIG_SMP
113 arch_local_irq_enable();
114#else
108 asm volatile( 115 asm volatile(
109 " or %0,epsw \n" 116 " or %0,epsw \n"
110 " nop \n" 117 " nop \n"
@@ -113,8 +120,21 @@ static inline void arch_safe_halt(void)
113 : 120 :
114 : "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP) 121 : "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP)
115 : "cc"); 122 : "cc");
123#endif
116} 124}
117 125
126#define __sleep_cpu() \
127do { \
128 asm volatile( \
129 " bset %1,(%0)\n" \
130 "1: btst %1,(%0)\n" \
131 " bne 1b\n" \
132 : \
133 : "i"(&CPUM), "i"(CPUM_SLEEP) \
134 : "cc" \
135 ); \
136} while (0)
137
118static inline void arch_local_cli(void) 138static inline void arch_local_cli(void)
119{ 139{
120 asm volatile( 140 asm volatile(
diff --git a/arch/mn10300/include/asm/pgtable.h b/arch/mn10300/include/asm/pgtable.h
index 05dda641af80..cd568bf5407e 100644
--- a/arch/mn10300/include/asm/pgtable.h
+++ b/arch/mn10300/include/asm/pgtable.h
@@ -90,9 +90,15 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
90 * The vmalloc() routines also leaves a hole of 4kB between each vmalloced 90 * The vmalloc() routines also leaves a hole of 4kB between each vmalloced
91 * area to catch addressing errors. 91 * area to catch addressing errors.
92 */ 92 */
93#ifndef __ASSEMBLY__
94#define VMALLOC_OFFSET (8UL * 1024 * 1024)
95#define VMALLOC_START (0x70000000UL)
96#define VMALLOC_END (0x7C000000UL)
97#else
93#define VMALLOC_OFFSET (8 * 1024 * 1024) 98#define VMALLOC_OFFSET (8 * 1024 * 1024)
94#define VMALLOC_START (0x70000000) 99#define VMALLOC_START (0x70000000)
95#define VMALLOC_END (0x7C000000) 100#define VMALLOC_END (0x7C000000)
101#endif
96 102
97#ifndef __ASSEMBLY__ 103#ifndef __ASSEMBLY__
98extern pte_t kernel_vmalloc_ptes[(VMALLOC_END - VMALLOC_START) / PAGE_SIZE]; 104extern pte_t kernel_vmalloc_ptes[(VMALLOC_END - VMALLOC_START) / PAGE_SIZE];
@@ -329,11 +335,7 @@ static inline int pte_exec_kernel(pte_t pte)
329 return 1; 335 return 1;
330} 336}
331 337
332/* 338#define PTE_FILE_MAX_BITS 30
333 * Bits 0 and 1 are taken, split up the 29 bits of offset
334 * into this range:
335 */
336#define PTE_FILE_MAX_BITS 29
337 339
338#define pte_to_pgoff(pte) (pte_val(pte) >> 2) 340#define pte_to_pgoff(pte) (pte_val(pte) >> 2)
339#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE) 341#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE)
@@ -379,8 +381,13 @@ static inline void ptep_mkdirty(pte_t *ptep)
379 * Macro to mark a page protection value as "uncacheable". On processors which 381 * Macro to mark a page protection value as "uncacheable". On processors which
380 * do not support it, this is a no-op. 382 * do not support it, this is a no-op.
381 */ 383 */
382#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_CACHE) 384#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHE)
383 385
386/*
387 * Macro to mark a page protection value as "Write-Through".
388 * On processors which do not support it, this is a no-op.
389 */
390#define pgprot_through(prot) __pgprot(pgprot_val(prot) | _PAGE_CACHE_WT)
384 391
385/* 392/*
386 * Conversion functions: convert a page and protection to a page entry, 393 * Conversion functions: convert a page and protection to a page entry,
diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h
index 0032fc76c8ba..75c422abcd6b 100644
--- a/arch/mn10300/include/asm/processor.h
+++ b/arch/mn10300/include/asm/processor.h
@@ -33,6 +33,8 @@ struct mm_struct;
33 __pc; \ 33 __pc; \
34}) 34})
35 35
36extern void get_mem_info(unsigned long *mem_base, unsigned long *mem_size);
37
36extern void show_registers(struct pt_regs *regs); 38extern void show_registers(struct pt_regs *regs);
37 39
38/* 40/*
@@ -43,17 +45,22 @@ extern void show_registers(struct pt_regs *regs);
43 45
44struct mn10300_cpuinfo { 46struct mn10300_cpuinfo {
45 int type; 47 int type;
46 unsigned long loops_per_sec; 48 unsigned long loops_per_jiffy;
47 char hard_math; 49 char hard_math;
48 unsigned long *pgd_quick;
49 unsigned long *pte_quick;
50 unsigned long pgtable_cache_sz;
51}; 50};
52 51
53extern struct mn10300_cpuinfo boot_cpu_data; 52extern struct mn10300_cpuinfo boot_cpu_data;
54 53
54#ifdef CONFIG_SMP
55#if CONFIG_NR_CPUS < 2 || CONFIG_NR_CPUS > 8
56# error Sorry, NR_CPUS should be 2 to 8
57#endif
58extern struct mn10300_cpuinfo cpu_data[];
59#define current_cpu_data cpu_data[smp_processor_id()]
60#else /* CONFIG_SMP */
55#define cpu_data &boot_cpu_data 61#define cpu_data &boot_cpu_data
56#define current_cpu_data boot_cpu_data 62#define current_cpu_data boot_cpu_data
63#endif /* CONFIG_SMP */
57 64
58extern void identify_cpu(struct mn10300_cpuinfo *); 65extern void identify_cpu(struct mn10300_cpuinfo *);
59extern void print_cpu_info(struct mn10300_cpuinfo *); 66extern void print_cpu_info(struct mn10300_cpuinfo *);
@@ -92,21 +99,21 @@ struct thread_struct {
92 unsigned long a3; /* kernel FP */ 99 unsigned long a3; /* kernel FP */
93 unsigned long wchan; 100 unsigned long wchan;
94 unsigned long usp; 101 unsigned long usp;
95 struct pt_regs *__frame; 102 struct pt_regs *frame;
96 unsigned long fpu_flags; 103 unsigned long fpu_flags;
97#define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */ 104#define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */
98#define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */ 105#define THREAD_HAS_FPU 0x00000002 /* T if this task owns the FPU right now */
99 struct fpu_state_struct fpu_state; 106 struct fpu_state_struct fpu_state;
100}; 107};
101 108
102#define INIT_THREAD \ 109#define INIT_THREAD \
103{ \ 110{ \
104 .uregs = init_uregs, \ 111 .uregs = init_uregs, \
105 .pc = 0, \ 112 .pc = 0, \
106 .sp = 0, \ 113 .sp = 0, \
107 .a3 = 0, \ 114 .a3 = 0, \
108 .wchan = 0, \ 115 .wchan = 0, \
109 .__frame = NULL, \ 116 .frame = NULL, \
110} 117}
111 118
112#define INIT_MMAP \ 119#define INIT_MMAP \
@@ -118,6 +125,19 @@ struct thread_struct {
118 * - need to discard the frame stacked by the kernel thread invoking the execve 125 * - need to discard the frame stacked by the kernel thread invoking the execve
119 * syscall (see RESTORE_ALL macro) 126 * syscall (see RESTORE_ALL macro)
120 */ 127 */
128#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) /* FIXME */
129#define start_thread(regs, new_pc, new_sp) do { \
130 int cpu; \
131 preempt_disable(); \
132 cpu = CPUID; \
133 set_fs(USER_DS); \
134 ___frame[cpu] = current->thread.uregs; \
135 ___frame[cpu]->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;\
136 ___frame[cpu]->pc = new_pc; \
137 ___frame[cpu]->sp = new_sp; \
138 preempt_enable(); \
139} while (0)
140#else /* CONFIG_SMP && CONFIG_PREEMPT */
121#define start_thread(regs, new_pc, new_sp) do { \ 141#define start_thread(regs, new_pc, new_sp) do { \
122 set_fs(USER_DS); \ 142 set_fs(USER_DS); \
123 __frame = current->thread.uregs; \ 143 __frame = current->thread.uregs; \
@@ -125,6 +145,7 @@ struct thread_struct {
125 __frame->pc = new_pc; \ 145 __frame->pc = new_pc; \
126 __frame->sp = new_sp; \ 146 __frame->sp = new_sp; \
127} while (0) 147} while (0)
148#endif /* CONFIG_SMP && CONFIG_PREEMPT */
128 149
129/* Free all resources held by a thread. */ 150/* Free all resources held by a thread. */
130extern void release_thread(struct task_struct *); 151extern void release_thread(struct task_struct *);
diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h
index 7c2e911052b6..c2b77bd3064a 100644
--- a/arch/mn10300/include/asm/ptrace.h
+++ b/arch/mn10300/include/asm/ptrace.h
@@ -40,7 +40,6 @@
40#define PT_PC 26 40#define PT_PC 26
41#define NR_PTREGS 27 41#define NR_PTREGS 27
42 42
43#ifndef __ASSEMBLY__
44/* 43/*
45 * This defines the way registers are stored in the event of an exception 44 * This defines the way registers are stored in the event of an exception
46 * - the strange order is due to the MOVM instruction 45 * - the strange order is due to the MOVM instruction
@@ -75,7 +74,6 @@ struct pt_regs {
75 unsigned long epsw; 74 unsigned long epsw;
76 unsigned long pc; 75 unsigned long pc;
77}; 76};
78#endif
79 77
80/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ 78/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
81#define PTRACE_GETREGS 12 79#define PTRACE_GETREGS 12
@@ -86,12 +84,13 @@ struct pt_regs {
86/* options set using PTRACE_SETOPTIONS */ 84/* options set using PTRACE_SETOPTIONS */
87#define PTRACE_O_TRACESYSGOOD 0x00000001 85#define PTRACE_O_TRACESYSGOOD 0x00000001
88 86
89#if defined(__KERNEL__) 87#ifdef __KERNEL__
90 88
89#ifdef CONFIG_SMP
90extern struct pt_regs *___frame[]; /* current frame pointer */
91#else
91extern struct pt_regs *__frame; /* current frame pointer */ 92extern struct pt_regs *__frame; /* current frame pointer */
92 93#endif
93#if !defined(__ASSEMBLY__)
94struct task_struct;
95 94
96#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) 95#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
97#define instruction_pointer(regs) ((regs)->pc) 96#define instruction_pointer(regs) ((regs)->pc)
@@ -100,9 +99,7 @@ extern void show_regs(struct pt_regs *);
100 99
101#define arch_has_single_step() (1) 100#define arch_has_single_step() (1)
102 101
103#endif /* !__ASSEMBLY */
104
105#define profile_pc(regs) ((regs)->pc) 102#define profile_pc(regs) ((regs)->pc)
106 103
107#endif /* __KERNEL__ */ 104#endif /* __KERNEL__ */
108#endif /* _ASM_PTRACE_H */ 105#endif /* _ASM_PTRACE_H */
diff --git a/arch/mn10300/include/asm/reset-regs.h b/arch/mn10300/include/asm/reset-regs.h
index 174523d50132..10c7502a113f 100644
--- a/arch/mn10300/include/asm/reset-regs.h
+++ b/arch/mn10300/include/asm/reset-regs.h
@@ -50,7 +50,7 @@ static inline void mn10300_proc_hard_reset(void)
50 RSTCTR |= RSTCTR_CHIPRST; 50 RSTCTR |= RSTCTR_CHIPRST;
51} 51}
52 52
53extern unsigned int watchdog_alert_counter; 53extern unsigned int watchdog_alert_counter[];
54 54
55extern void watchdog_go(void); 55extern void watchdog_go(void);
56extern asmlinkage void watchdog_handler(void); 56extern asmlinkage void watchdog_handler(void);
diff --git a/arch/mn10300/include/asm/rtc.h b/arch/mn10300/include/asm/rtc.h
index c295194cc703..6c14bb1d0d9b 100644
--- a/arch/mn10300/include/asm/rtc.h
+++ b/arch/mn10300/include/asm/rtc.h
@@ -15,25 +15,14 @@
15 15
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18extern void check_rtc_time(void);
19extern void __init calibrate_clock(void); 18extern void __init calibrate_clock(void);
20extern unsigned long __init get_initial_rtc_time(void);
21 19
22#else /* !CONFIG_MN10300_RTC */ 20#else /* !CONFIG_MN10300_RTC */
23 21
24static inline void check_rtc_time(void)
25{
26}
27
28static inline void calibrate_clock(void) 22static inline void calibrate_clock(void)
29{ 23{
30} 24}
31 25
32static inline unsigned long get_initial_rtc_time(void)
33{
34 return 0;
35}
36
37#endif /* !CONFIG_MN10300_RTC */ 26#endif /* !CONFIG_MN10300_RTC */
38 27
39#include <asm-generic/rtc.h> 28#include <asm-generic/rtc.h>
diff --git a/arch/mn10300/include/asm/rwlock.h b/arch/mn10300/include/asm/rwlock.h
new file mode 100644
index 000000000000..6d594d4a0e10
--- /dev/null
+++ b/arch/mn10300/include/asm/rwlock.h
@@ -0,0 +1,125 @@
1/*
2 * Helpers used by both rw spinlocks and rw semaphores.
3 *
4 * Based in part on code from semaphore.h and
5 * spinlock.h Copyright 1996 Linus Torvalds.
6 *
7 * Copyright 1999 Red Hat, Inc.
8 *
9 * Written by Benjamin LaHaise.
10 *
11 * Modified by Matsushita Electric Industrial Co., Ltd.
12 * Modifications:
13 * 13-Nov-2006 MEI Temporarily delete lock functions for SMP support.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at your option)
18 * any later version.
19 */
20#ifndef _ASM_RWLOCK_H
21#define _ASM_RWLOCK_H
22
23#define RW_LOCK_BIAS 0x01000000
24
25#ifndef CONFIG_SMP
26
27typedef struct { unsigned long a[100]; } __dummy_lock_t;
28#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
29
30#define RW_LOCK_BIAS_STR "0x01000000"
31
32#define __build_read_lock_ptr(rw, helper) \
33 do { \
34 asm volatile( \
35 " mov (%0),d3 \n" \
36 " sub 1,d3 \n" \
37 " mov d3,(%0) \n" \
38 " blt 1f \n" \
39 " bra 2f \n" \
40 "1: jmp 3f \n" \
41 "2: \n" \
42 " .section .text.lock,\"ax\" \n" \
43 "3: call "helper"[],0 \n" \
44 " jmp 2b \n" \
45 " .previous" \
46 : \
47 : "d" (rw) \
48 : "memory", "d3", "cc"); \
49 } while (0)
50
51#define __build_read_lock_const(rw, helper) \
52 do { \
53 asm volatile( \
54 " mov (%0),d3 \n" \
55 " sub 1,d3 \n" \
56 " mov d3,(%0) \n" \
57 " blt 1f \n" \
58 " bra 2f \n" \
59 "1: jmp 3f \n" \
60 "2: \n" \
61 " .section .text.lock,\"ax\" \n" \
62 "3: call "helper"[],0 \n" \
63 " jmp 2b \n" \
64 " .previous" \
65 : \
66 : "d" (rw) \
67 : "memory", "d3", "cc"); \
68 } while (0)
69
70#define __build_read_lock(rw, helper) \
71 do { \
72 if (__builtin_constant_p(rw)) \
73 __build_read_lock_const(rw, helper); \
74 else \
75 __build_read_lock_ptr(rw, helper); \
76 } while (0)
77
78#define __build_write_lock_ptr(rw, helper) \
79 do { \
80 asm volatile( \
81 " mov (%0),d3 \n" \
82 " sub 1,d3 \n" \
83 " mov d3,(%0) \n" \
84 " blt 1f \n" \
85 " bra 2f \n" \
86 "1: jmp 3f \n" \
87 "2: \n" \
88 " .section .text.lock,\"ax\" \n" \
89 "3: call "helper"[],0 \n" \
90 " jmp 2b \n" \
91 " .previous" \
92 : \
93 : "d" (rw) \
94 : "memory", "d3", "cc"); \
95 } while (0)
96
97#define __build_write_lock_const(rw, helper) \
98 do { \
99 asm volatile( \
100 " mov (%0),d3 \n" \
101 " sub 1,d3 \n" \
102 " mov d3,(%0) \n" \
103 " blt 1f \n" \
104 " bra 2f \n" \
105 "1: jmp 3f \n" \
106 "2: \n" \
107 " .section .text.lock,\"ax\" \n" \
108 "3: call "helper"[],0 \n" \
109 " jmp 2b \n" \
110 " .previous" \
111 : \
112 : "d" (rw) \
113 : "memory", "d3", "cc"); \
114 } while (0)
115
116#define __build_write_lock(rw, helper) \
117 do { \
118 if (__builtin_constant_p(rw)) \
119 __build_write_lock_const(rw, helper); \
120 else \
121 __build_write_lock_ptr(rw, helper); \
122 } while (0)
123
124#endif /* CONFIG_SMP */
125#endif /* _ASM_RWLOCK_H */
diff --git a/arch/mn10300/include/asm/serial-regs.h b/arch/mn10300/include/asm/serial-regs.h
index 6498469e93ac..8320cda32f5a 100644
--- a/arch/mn10300/include/asm/serial-regs.h
+++ b/arch/mn10300/include/asm/serial-regs.h
@@ -20,18 +20,25 @@
20/* serial port 0 */ 20/* serial port 0 */
21#define SC0CTR __SYSREG(0xd4002000, u16) /* control reg */ 21#define SC0CTR __SYSREG(0xd4002000, u16) /* control reg */
22#define SC01CTR_CK 0x0007 /* clock source select */ 22#define SC01CTR_CK 0x0007 /* clock source select */
23#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */
24#define SC1CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow (serial port 1 only) */
25#define SC01CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */ 23#define SC01CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */
26#define SC01CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */ 24#define SC01CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */
25#define SC01CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */
26#define SC01CTR_CK_EXTERN 0x0007 /* - external closk */
27#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
28#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */
27#define SC0CTR_CK_TM2UFLOW_2 0x0003 /* - 1/2 timer 2 underflow (serial port 0 only) */ 29#define SC0CTR_CK_TM2UFLOW_2 0x0003 /* - 1/2 timer 2 underflow (serial port 0 only) */
28#define SC1CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow (serial port 1 only) */ 30#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 0 underflow (serial port 0 only) */
29#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 1 underflow (serial port 0 only) */
30#define SC1CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 2 underflow (serial port 1 only) */
31#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */ 31#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */
32#define SC1CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow (serial port 1 only) */
33#define SC1CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow (serial port 1 only) */
34#define SC1CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 1 underflow (serial port 1 only) */
32#define SC1CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow (serial port 1 only) */ 35#define SC1CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow (serial port 1 only) */
33#define SC01CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */ 36#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
34#define SC01CTR_CK_EXTERN 0x0007 /* - external closk */ 37#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */
38#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 0 underflow (serial port 0 only) */
39#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */
40#define SC1CTR_CK_TM12UFLOW_8 0x0000 /* - 1/8 timer 12 underflow (serial port 1 only) */
41#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
35#define SC01CTR_STB 0x0008 /* stop bit select */ 42#define SC01CTR_STB 0x0008 /* stop bit select */
36#define SC01CTR_STB_1BIT 0x0000 /* - 1 stop bit */ 43#define SC01CTR_STB_1BIT 0x0000 /* - 1 stop bit */
37#define SC01CTR_STB_2BIT 0x0008 /* - 2 stop bits */ 44#define SC01CTR_STB_2BIT 0x0008 /* - 2 stop bits */
@@ -100,11 +107,23 @@
100 107
101/* serial port 2 */ 108/* serial port 2 */
102#define SC2CTR __SYSREG(0xd4002020, u16) /* control reg */ 109#define SC2CTR __SYSREG(0xd4002020, u16) /* control reg */
110#ifdef CONFIG_AM33_2
103#define SC2CTR_CK 0x0003 /* clock source select */ 111#define SC2CTR_CK 0x0003 /* clock source select */
104#define SC2CTR_CK_TM10UFLOW 0x0000 /* - timer 10 underflow */ 112#define SC2CTR_CK_TM10UFLOW 0x0000 /* - timer 10 underflow */
105#define SC2CTR_CK_TM2UFLOW 0x0001 /* - timer 2 underflow */ 113#define SC2CTR_CK_TM2UFLOW 0x0001 /* - timer 2 underflow */
106#define SC2CTR_CK_EXTERN 0x0002 /* - external closk */ 114#define SC2CTR_CK_EXTERN 0x0002 /* - external closk */
107#define SC2CTR_CK_TM3UFLOW 0x0003 /* - timer 3 underflow */ 115#define SC2CTR_CK_TM3UFLOW 0x0003 /* - timer 3 underflow */
116#else /* CONFIG_AM33_2 */
117#define SC2CTR_CK 0x0007 /* clock source select */
118#define SC2CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow */
119#define SC2CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */
120#define SC2CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */
121#define SC2CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow */
122#define SC2CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 1 underflow */
123#define SC2CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow */
124#define SC2CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */
125#define SC2CTR_CK_EXTERN 0x0007 /* - external closk */
126#endif /* CONFIG_AM33_2 */
108#define SC2CTR_STB 0x0008 /* stop bit select */ 127#define SC2CTR_STB 0x0008 /* stop bit select */
109#define SC2CTR_STB_1BIT 0x0000 /* - 1 stop bit */ 128#define SC2CTR_STB_1BIT 0x0000 /* - 1 stop bit */
110#define SC2CTR_STB_2BIT 0x0008 /* - 2 stop bits */ 129#define SC2CTR_STB_2BIT 0x0008 /* - 2 stop bits */
@@ -134,9 +153,14 @@
134#define SC2ICR_RES 0x04 /* receive error select */ 153#define SC2ICR_RES 0x04 /* receive error select */
135#define SC2ICR_RI 0x01 /* receive interrupt cause */ 154#define SC2ICR_RI 0x01 /* receive interrupt cause */
136 155
137#define SC2TXB __SYSREG(0xd4002018, u8) /* transmit buffer reg */ 156#define SC2TXB __SYSREG(0xd4002028, u8) /* transmit buffer reg */
138#define SC2RXB __SYSREG(0xd4002019, u8) /* receive buffer reg */ 157#define SC2RXB __SYSREG(0xd4002029, u8) /* receive buffer reg */
139#define SC2STR __SYSREG(0xd400201c, u8) /* status reg */ 158
159#ifdef CONFIG_AM33_2
160#define SC2STR __SYSREG(0xd400202c, u8) /* status reg */
161#else /* CONFIG_AM33_2 */
162#define SC2STR __SYSREG(0xd400202c, u16) /* status reg */
163#endif /* CONFIG_AM33_2 */
140#define SC2STR_OEF 0x0001 /* overrun error found */ 164#define SC2STR_OEF 0x0001 /* overrun error found */
141#define SC2STR_PEF 0x0002 /* parity error found */ 165#define SC2STR_PEF 0x0002 /* parity error found */
142#define SC2STR_FEF 0x0004 /* framing error found */ 166#define SC2STR_FEF 0x0004 /* framing error found */
@@ -146,10 +170,17 @@
146#define SC2STR_RXF 0x0040 /* receive status */ 170#define SC2STR_RXF 0x0040 /* receive status */
147#define SC2STR_TXF 0x0080 /* transmit status */ 171#define SC2STR_TXF 0x0080 /* transmit status */
148 172
173#ifdef CONFIG_AM33_2
149#define SC2TIM __SYSREG(0xd400202d, u8) /* status reg */ 174#define SC2TIM __SYSREG(0xd400202d, u8) /* status reg */
175#endif
150 176
177#ifdef CONFIG_AM33_2
151#define SC2RXIRQ 24 /* serial 2 Receive IRQ */ 178#define SC2RXIRQ 24 /* serial 2 Receive IRQ */
152#define SC2TXIRQ 25 /* serial 2 Transmit IRQ */ 179#define SC2TXIRQ 25 /* serial 2 Transmit IRQ */
180#else /* CONFIG_AM33_2 */
181#define SC2RXIRQ 68 /* serial 2 Receive IRQ */
182#define SC2TXIRQ 69 /* serial 2 Transmit IRQ */
183#endif /* CONFIG_AM33_2 */
153 184
154#define SC2RXICR GxICR(SC2RXIRQ) /* serial 2 receive intr ctrl reg */ 185#define SC2RXICR GxICR(SC2RXIRQ) /* serial 2 receive intr ctrl reg */
155#define SC2TXICR GxICR(SC2TXIRQ) /* serial 2 transmit intr ctrl reg */ 186#define SC2TXICR GxICR(SC2TXIRQ) /* serial 2 transmit intr ctrl reg */
diff --git a/arch/mn10300/include/asm/serial.h b/arch/mn10300/include/asm/serial.h
index a29445cddd6f..23a799293599 100644
--- a/arch/mn10300/include/asm/serial.h
+++ b/arch/mn10300/include/asm/serial.h
@@ -9,10 +9,8 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12/* 12#ifndef _ASM_SERIAL_H
13 * The ASB2305 has an 18.432 MHz clock the UART 13#define _ASM_SERIAL_H
14 */
15#define BASE_BAUD (18432000 / 16)
16 14
17/* Standard COM flags (except for COM4, because of the 8514 problem) */ 15/* Standard COM flags (except for COM4, because of the 8514 problem) */
18#ifdef CONFIG_SERIAL_DETECT_IRQ 16#ifdef CONFIG_SERIAL_DETECT_IRQ
@@ -34,3 +32,5 @@
34#endif 32#endif
35 33
36#include <unit/serial.h> 34#include <unit/serial.h>
35
36#endif /* _ASM_SERIAL_H */
diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h
index 4eb8c61b7dab..b8585b4e8cdf 100644
--- a/arch/mn10300/include/asm/smp.h
+++ b/arch/mn10300/include/asm/smp.h
@@ -3,6 +3,16 @@
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * Modified by Matsushita Electric Industrial Co., Ltd.
7 * Modifications:
8 * 13-Nov-2006 MEI Define IPI-IRQ number and add inline/macro function
9 * for SMP support.
10 * 22-Jan-2007 MEI Add the define related to SMP_BOOT_IRQ.
11 * 23-Feb-2007 MEI Add the define related to SMP icahce invalidate.
12 * 23-Jun-2008 MEI Delete INTC_IPI.
13 * 22-Jul-2008 MEI Add smp_nmi_call_function and related defines.
14 * 04-Aug-2008 MEI Delete USE_DOIRQ_CACHE_IPI.
15 *
6 * This program is free software; you can redistribute it and/or 16 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence 17 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version 18 * as published by the Free Software Foundation; either version
@@ -11,8 +21,98 @@
11#ifndef _ASM_SMP_H 21#ifndef _ASM_SMP_H
12#define _ASM_SMP_H 22#define _ASM_SMP_H
13 23
24#ifndef __ASSEMBLY__
25#include <linux/threads.h>
26#include <linux/cpumask.h>
27#endif
28
14#ifdef CONFIG_SMP 29#ifdef CONFIG_SMP
15#error SMP not yet supported for MN10300 30#include <proc/smp-regs.h>
31
32#define RESCHEDULE_IPI 63
33#define CALL_FUNC_SINGLE_IPI 192
34#define LOCAL_TIMER_IPI 193
35#define FLUSH_CACHE_IPI 194
36#define CALL_FUNCTION_NMI_IPI 195
37#define GDB_NMI_IPI 196
38
39#define SMP_BOOT_IRQ 195
40
41#define RESCHEDULE_GxICR_LV GxICR_LEVEL_6
42#define CALL_FUNCTION_GxICR_LV GxICR_LEVEL_4
43#define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4
44#define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0
45#define SMP_BOOT_GxICR_LV GxICR_LEVEL_0
46
47#define TIME_OUT_COUNT_BOOT_IPI 100
48#define DELAY_TIME_BOOT_IPI 75000
49
50
51#ifndef __ASSEMBLY__
52
53/**
54 * raw_smp_processor_id - Determine the raw CPU ID of the CPU running it
55 *
56 * What we really want to do is to use the CPUID hardware CPU register to get
57 * this information, but accesses to that aren't cached, and run at system bus
58 * speed, not CPU speed. A copy of this value is, however, stored in the
59 * thread_info struct, and that can be cached.
60 *
61 * An alternate way of dealing with this could be to use the EPSW.S bits to
62 * cache this information for systems with up to four CPUs.
63 */
64#if 0
65#define raw_smp_processor_id() (CPUID)
66#else
67#define raw_smp_processor_id() (current_thread_info()->cpu)
16#endif 68#endif
17 69
70static inline int cpu_logical_map(int cpu)
71{
72 return cpu;
73}
74
75static inline int cpu_number_map(int cpu)
76{
77 return cpu;
78}
79
80
81extern cpumask_t cpu_boot_map;
82
83extern void smp_init_cpus(void);
84extern void smp_cache_interrupt(void);
85extern void send_IPI_allbutself(int irq);
86extern int smp_nmi_call_function(smp_call_func_t func, void *info, int wait);
87
88extern void arch_send_call_function_single_ipi(int cpu);
89extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
90
91#ifdef CONFIG_HOTPLUG_CPU
92extern int __cpu_disable(void);
93extern void __cpu_die(unsigned int cpu);
94#endif /* CONFIG_HOTPLUG_CPU */
95
96#ifdef CONFIG_PREEMPT /* FIXME */
97#define __frame \
98 ({ \
99 struct pt_regs *f; \
100 preempt_disable(); \
101 f = ___frame[CPUID]; \
102 preempt_enable(); \
103 f; \
104 })
105#else
106#define __frame ___frame[CPUID]
18#endif 107#endif
108
109#endif /* __ASSEMBLY__ */
110#else /* CONFIG_SMP */
111#ifndef __ASSEMBLY__
112
113static inline void smp_init_cpus(void) {}
114
115#endif /* __ASSEMBLY__ */
116#endif /* CONFIG_SMP */
117
118#endif /* _ASM_SMP_H */
diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h
index 4bf9c8b169e0..93429154e898 100644
--- a/arch/mn10300/include/asm/spinlock.h
+++ b/arch/mn10300/include/asm/spinlock.h
@@ -11,6 +11,183 @@
11#ifndef _ASM_SPINLOCK_H 11#ifndef _ASM_SPINLOCK_H
12#define _ASM_SPINLOCK_H 12#define _ASM_SPINLOCK_H
13 13
14#error SMP spinlocks not implemented for MN10300 14#include <asm/atomic.h>
15#include <asm/rwlock.h>
16#include <asm/page.h>
15 17
18/*
19 * Simple spin lock operations. There are two variants, one clears IRQ's
20 * on the local processor, one does not.
21 *
22 * We make no fairness assumptions. They have a cost.
23 */
24
25#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) != 0)
26#define arch_spin_unlock_wait(x) do { barrier(); } while (arch_spin_is_locked(x))
27
28static inline void arch_spin_unlock(arch_spinlock_t *lock)
29{
30 asm volatile(
31 " bclr 1,(0,%0) \n"
32 :
33 : "a"(&lock->slock)
34 : "memory", "cc");
35}
36
37static inline int arch_spin_trylock(arch_spinlock_t *lock)
38{
39 int ret;
40
41 asm volatile(
42 " mov 1,%0 \n"
43 " bset %0,(%1) \n"
44 " bne 1f \n"
45 " clr %0 \n"
46 "1: xor 1,%0 \n"
47 : "=d"(ret)
48 : "a"(&lock->slock)
49 : "memory", "cc");
50
51 return ret;
52}
53
54static inline void arch_spin_lock(arch_spinlock_t *lock)
55{
56 asm volatile(
57 "1: bset 1,(0,%0) \n"
58 " bne 1b \n"
59 :
60 : "a"(&lock->slock)
61 : "memory", "cc");
62}
63
64static inline void arch_spin_lock_flags(arch_spinlock_t *lock,
65 unsigned long flags)
66{
67 int temp;
68
69 asm volatile(
70 "1: bset 1,(0,%2) \n"
71 " beq 3f \n"
72 " mov %1,epsw \n"
73 "2: mov (0,%2),%0 \n"
74 " or %0,%0 \n"
75 " bne 2b \n"
76 " mov %3,%0 \n"
77 " mov %0,epsw \n"
78 " nop \n"
79 " nop \n"
80 " bra 1b\n"
81 "3: \n"
82 : "=&d" (temp)
83 : "d" (flags), "a"(&lock->slock), "i"(EPSW_IE | MN10300_CLI_LEVEL)
84 : "memory", "cc");
85}
86
87#ifdef __KERNEL__
88
89/*
90 * Read-write spinlocks, allowing multiple readers
91 * but only one writer.
92 *
93 * NOTE! it is quite common to have readers in interrupts
94 * but no interrupt writers. For those circumstances we
95 * can "mix" irq-safe locks - any writer needs to get a
96 * irq-safe write-lock, but readers can get non-irqsafe
97 * read-locks.
98 */
99
100/**
101 * read_can_lock - would read_trylock() succeed?
102 * @lock: the rwlock in question.
103 */
104#define arch_read_can_lock(x) ((int)(x)->lock > 0)
105
106/**
107 * write_can_lock - would write_trylock() succeed?
108 * @lock: the rwlock in question.
109 */
110#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
111
112/*
113 * On mn10300, we implement read-write locks as a 32-bit counter
114 * with the high bit (sign) being the "contended" bit.
115 */
116static inline void arch_read_lock(arch_rwlock_t *rw)
117{
118#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
119 __build_read_lock(rw, "__read_lock_failed");
120#else
121 {
122 atomic_t *count = (atomic_t *)rw;
123 while (atomic_dec_return(count) < 0)
124 atomic_inc(count);
125 }
126#endif
127}
128
129static inline void arch_write_lock(arch_rwlock_t *rw)
130{
131#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
132 __build_write_lock(rw, "__write_lock_failed");
133#else
134 {
135 atomic_t *count = (atomic_t *)rw;
136 while (!atomic_sub_and_test(RW_LOCK_BIAS, count))
137 atomic_add(RW_LOCK_BIAS, count);
138 }
139#endif
140}
141
142static inline void arch_read_unlock(arch_rwlock_t *rw)
143{
144#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
145 __build_read_unlock(rw);
146#else
147 {
148 atomic_t *count = (atomic_t *)rw;
149 atomic_inc(count);
150 }
151#endif
152}
153
154static inline void arch_write_unlock(arch_rwlock_t *rw)
155{
156#if 0 //def CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
157 __build_write_unlock(rw);
158#else
159 {
160 atomic_t *count = (atomic_t *)rw;
161 atomic_add(RW_LOCK_BIAS, count);
162 }
163#endif
164}
165
166static inline int arch_read_trylock(arch_rwlock_t *lock)
167{
168 atomic_t *count = (atomic_t *)lock;
169 atomic_dec(count);
170 if (atomic_read(count) >= 0)
171 return 1;
172 atomic_inc(count);
173 return 0;
174}
175
176static inline int arch_write_trylock(arch_rwlock_t *lock)
177{
178 atomic_t *count = (atomic_t *)lock;
179 if (atomic_sub_and_test(RW_LOCK_BIAS, count))
180 return 1;
181 atomic_add(RW_LOCK_BIAS, count);
182 return 0;
183}
184
185#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
186#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
187
188#define _raw_spin_relax(lock) cpu_relax()
189#define _raw_read_relax(lock) cpu_relax()
190#define _raw_write_relax(lock) cpu_relax()
191
192#endif /* __KERNEL__ */
16#endif /* _ASM_SPINLOCK_H */ 193#endif /* _ASM_SPINLOCK_H */
diff --git a/arch/mn10300/include/asm/spinlock_types.h b/arch/mn10300/include/asm/spinlock_types.h
new file mode 100644
index 000000000000..653dc519b405
--- /dev/null
+++ b/arch/mn10300/include/asm/spinlock_types.h
@@ -0,0 +1,20 @@
1#ifndef _ASM_SPINLOCK_TYPES_H
2#define _ASM_SPINLOCK_TYPES_H
3
4#ifndef __LINUX_SPINLOCK_TYPES_H
5# error "please don't include this file directly"
6#endif
7
8typedef struct arch_spinlock {
9 unsigned int slock;
10} arch_spinlock_t;
11
12#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
13
14typedef struct {
15 unsigned int lock;
16} arch_rwlock_t;
17
18#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
19
20#endif /* _ASM_SPINLOCK_TYPES_H */
diff --git a/arch/mn10300/include/asm/system.h b/arch/mn10300/include/asm/system.h
index 7de90bc4cf80..8ff3e5aaca41 100644
--- a/arch/mn10300/include/asm/system.h
+++ b/arch/mn10300/include/asm/system.h
@@ -12,6 +12,7 @@
12#define _ASM_SYSTEM_H 12#define _ASM_SYSTEM_H
13 13
14#include <asm/cpu-regs.h> 14#include <asm/cpu-regs.h>
15#include <asm/intctl-regs.h>
15 16
16#ifdef __KERNEL__ 17#ifdef __KERNEL__
17#ifndef __ASSEMBLY__ 18#ifndef __ASSEMBLY__
@@ -57,8 +58,6 @@ do { \
57 58
58#define nop() asm volatile ("nop") 59#define nop() asm volatile ("nop")
59 60
60#endif /* !__ASSEMBLY__ */
61
62/* 61/*
63 * Force strict CPU ordering. 62 * Force strict CPU ordering.
64 * And yes, this is required on UP too when we're talking 63 * And yes, this is required on UP too when we're talking
@@ -85,17 +84,19 @@ do { \
85#define smp_mb() mb() 84#define smp_mb() mb()
86#define smp_rmb() rmb() 85#define smp_rmb() rmb()
87#define smp_wmb() wmb() 86#define smp_wmb() wmb()
88#else 87#define set_mb(var, value) do { xchg(&var, value); } while (0)
88#else /* CONFIG_SMP */
89#define smp_mb() barrier() 89#define smp_mb() barrier()
90#define smp_rmb() barrier() 90#define smp_rmb() barrier()
91#define smp_wmb() barrier() 91#define smp_wmb() barrier()
92#endif
93
94#define set_mb(var, value) do { var = value; mb(); } while (0) 92#define set_mb(var, value) do { var = value; mb(); } while (0)
93#endif /* CONFIG_SMP */
94
95#define set_wmb(var, value) do { var = value; wmb(); } while (0) 95#define set_wmb(var, value) do { var = value; wmb(); } while (0)
96 96
97#define read_barrier_depends() do {} while (0) 97#define read_barrier_depends() do {} while (0)
98#define smp_read_barrier_depends() do {} while (0) 98#define smp_read_barrier_depends() do {} while (0)
99 99
100#endif /* !__ASSEMBLY__ */
100#endif /* __KERNEL__ */ 101#endif /* __KERNEL__ */
101#endif /* _ASM_SYSTEM_H */ 102#endif /* _ASM_SYSTEM_H */
diff --git a/arch/mn10300/include/asm/timer-regs.h b/arch/mn10300/include/asm/timer-regs.h
index 1d883b7f94ab..c634977caf66 100644
--- a/arch/mn10300/include/asm/timer-regs.h
+++ b/arch/mn10300/include/asm/timer-regs.h
@@ -17,21 +17,27 @@
17 17
18#ifdef __KERNEL__ 18#ifdef __KERNEL__
19 19
20/* timer prescalar control */ 20/*
21 * Timer prescalar control
22 */
21#define TMPSCNT __SYSREG(0xd4003071, u8) /* timer prescaler control */ 23#define TMPSCNT __SYSREG(0xd4003071, u8) /* timer prescaler control */
22#define TMPSCNT_ENABLE 0x80 /* timer prescaler enable */ 24#define TMPSCNT_ENABLE 0x80 /* timer prescaler enable */
23#define TMPSCNT_DISABLE 0x00 /* timer prescaler disable */ 25#define TMPSCNT_DISABLE 0x00 /* timer prescaler disable */
24 26
25/* 8 bit timers */ 27/*
28 * 8-bit timers
29 */
26#define TM0MD __SYSREG(0xd4003000, u8) /* timer 0 mode register */ 30#define TM0MD __SYSREG(0xd4003000, u8) /* timer 0 mode register */
27#define TM0MD_SRC 0x07 /* timer source */ 31#define TM0MD_SRC 0x07 /* timer source */
28#define TM0MD_SRC_IOCLK 0x00 /* - IOCLK */ 32#define TM0MD_SRC_IOCLK 0x00 /* - IOCLK */
29#define TM0MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ 33#define TM0MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
30#define TM0MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ 34#define TM0MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
31#define TM0MD_SRC_TM2IO 0x03 /* - TM2IO pin input */
32#define TM0MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 35#define TM0MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
33#define TM0MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 36#define TM0MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
37#if defined(CONFIG_AM33_2)
38#define TM0MD_SRC_TM2IO 0x03 /* - TM2IO pin input */
34#define TM0MD_SRC_TM0IO 0x07 /* - TM0IO pin input */ 39#define TM0MD_SRC_TM0IO 0x07 /* - TM0IO pin input */
40#endif /* CONFIG_AM33_2 */
35#define TM0MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 41#define TM0MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
36#define TM0MD_COUNT_ENABLE 0x80 /* timer count enable */ 42#define TM0MD_COUNT_ENABLE 0x80 /* timer count enable */
37 43
@@ -43,7 +49,9 @@
43#define TM1MD_SRC_TM0CASCADE 0x03 /* - cascade with timer 0 */ 49#define TM1MD_SRC_TM0CASCADE 0x03 /* - cascade with timer 0 */
44#define TM1MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 50#define TM1MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
45#define TM1MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 51#define TM1MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
52#if defined(CONFIG_AM33_2)
46#define TM1MD_SRC_TM1IO 0x07 /* - TM1IO pin input */ 53#define TM1MD_SRC_TM1IO 0x07 /* - TM1IO pin input */
54#endif /* CONFIG_AM33_2 */
47#define TM1MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 55#define TM1MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
48#define TM1MD_COUNT_ENABLE 0x80 /* timer count enable */ 56#define TM1MD_COUNT_ENABLE 0x80 /* timer count enable */
49 57
@@ -55,7 +63,9 @@
55#define TM2MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 1 */ 63#define TM2MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 1 */
56#define TM2MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 64#define TM2MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
57#define TM2MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 65#define TM2MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
66#if defined(CONFIG_AM33_2)
58#define TM2MD_SRC_TM2IO 0x07 /* - TM2IO pin input */ 67#define TM2MD_SRC_TM2IO 0x07 /* - TM2IO pin input */
68#endif /* CONFIG_AM33_2 */
59#define TM2MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 69#define TM2MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
60#define TM2MD_COUNT_ENABLE 0x80 /* timer count enable */ 70#define TM2MD_COUNT_ENABLE 0x80 /* timer count enable */
61 71
@@ -64,11 +74,13 @@
64#define TM3MD_SRC_IOCLK 0x00 /* - IOCLK */ 74#define TM3MD_SRC_IOCLK 0x00 /* - IOCLK */
65#define TM3MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ 75#define TM3MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
66#define TM3MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ 76#define TM3MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
67#define TM3MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 2 */ 77#define TM3MD_SRC_TM2CASCADE 0x03 /* - cascade with timer 2 */
68#define TM3MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 78#define TM3MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
69#define TM3MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 79#define TM3MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
70#define TM3MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 80#define TM3MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
81#if defined(CONFIG_AM33_2)
71#define TM3MD_SRC_TM3IO 0x07 /* - TM3IO pin input */ 82#define TM3MD_SRC_TM3IO 0x07 /* - TM3IO pin input */
83#endif /* CONFIG_AM33_2 */
72#define TM3MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 84#define TM3MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
73#define TM3MD_COUNT_ENABLE 0x80 /* timer count enable */ 85#define TM3MD_COUNT_ENABLE 0x80 /* timer count enable */
74 86
@@ -96,7 +108,9 @@
96#define TM2ICR GxICR(TM2IRQ) /* timer 2 uflow intr ctrl reg */ 108#define TM2ICR GxICR(TM2IRQ) /* timer 2 uflow intr ctrl reg */
97#define TM3ICR GxICR(TM3IRQ) /* timer 3 uflow intr ctrl reg */ 109#define TM3ICR GxICR(TM3IRQ) /* timer 3 uflow intr ctrl reg */
98 110
99/* 16-bit timers 4,5 & 7-11 */ 111/*
112 * 16-bit timers 4,5 & 7-15
113 */
100#define TM4MD __SYSREG(0xd4003080, u8) /* timer 4 mode register */ 114#define TM4MD __SYSREG(0xd4003080, u8) /* timer 4 mode register */
101#define TM4MD_SRC 0x07 /* timer source */ 115#define TM4MD_SRC 0x07 /* timer source */
102#define TM4MD_SRC_IOCLK 0x00 /* - IOCLK */ 116#define TM4MD_SRC_IOCLK 0x00 /* - IOCLK */
@@ -105,7 +119,9 @@
105#define TM4MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 119#define TM4MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
106#define TM4MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 120#define TM4MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
107#define TM4MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 121#define TM4MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
122#if defined(CONFIG_AM33_2)
108#define TM4MD_SRC_TM4IO 0x07 /* - TM4IO pin input */ 123#define TM4MD_SRC_TM4IO 0x07 /* - TM4IO pin input */
124#endif /* CONFIG_AM33_2 */
109#define TM4MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 125#define TM4MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
110#define TM4MD_COUNT_ENABLE 0x80 /* timer count enable */ 126#define TM4MD_COUNT_ENABLE 0x80 /* timer count enable */
111 127
@@ -118,7 +134,11 @@
118#define TM5MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 134#define TM5MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
119#define TM5MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 135#define TM5MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
120#define TM5MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 136#define TM5MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
137#if defined(CONFIG_AM33_2)
121#define TM5MD_SRC_TM5IO 0x07 /* - TM5IO pin input */ 138#define TM5MD_SRC_TM5IO 0x07 /* - TM5IO pin input */
139#else /* !CONFIG_AM33_2 */
140#define TM5MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
141#endif /* CONFIG_AM33_2 */
122#define TM5MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 142#define TM5MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
123#define TM5MD_COUNT_ENABLE 0x80 /* timer count enable */ 143#define TM5MD_COUNT_ENABLE 0x80 /* timer count enable */
124 144
@@ -130,7 +150,9 @@
130#define TM7MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 150#define TM7MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
131#define TM7MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 151#define TM7MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
132#define TM7MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 152#define TM7MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
153#if defined(CONFIG_AM33_2)
133#define TM7MD_SRC_TM7IO 0x07 /* - TM7IO pin input */ 154#define TM7MD_SRC_TM7IO 0x07 /* - TM7IO pin input */
155#endif /* CONFIG_AM33_2 */
134#define TM7MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 156#define TM7MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
135#define TM7MD_COUNT_ENABLE 0x80 /* timer count enable */ 157#define TM7MD_COUNT_ENABLE 0x80 /* timer count enable */
136 158
@@ -143,7 +165,11 @@
143#define TM8MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 165#define TM8MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
144#define TM8MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 166#define TM8MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
145#define TM8MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 167#define TM8MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
168#if defined(CONFIG_AM33_2)
146#define TM8MD_SRC_TM8IO 0x07 /* - TM8IO pin input */ 169#define TM8MD_SRC_TM8IO 0x07 /* - TM8IO pin input */
170#else /* !CONFIG_AM33_2 */
171#define TM8MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
172#endif /* CONFIG_AM33_2 */
147#define TM8MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 173#define TM8MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
148#define TM8MD_COUNT_ENABLE 0x80 /* timer count enable */ 174#define TM8MD_COUNT_ENABLE 0x80 /* timer count enable */
149 175
@@ -156,7 +182,11 @@
156#define TM9MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 182#define TM9MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
157#define TM9MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 183#define TM9MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
158#define TM9MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 184#define TM9MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
185#if defined(CONFIG_AM33_2)
159#define TM9MD_SRC_TM9IO 0x07 /* - TM9IO pin input */ 186#define TM9MD_SRC_TM9IO 0x07 /* - TM9IO pin input */
187#else /* !CONFIG_AM33_2 */
188#define TM9MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
189#endif /* CONFIG_AM33_2 */
160#define TM9MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 190#define TM9MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
161#define TM9MD_COUNT_ENABLE 0x80 /* timer count enable */ 191#define TM9MD_COUNT_ENABLE 0x80 /* timer count enable */
162 192
@@ -169,7 +199,11 @@
169#define TM10MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 199#define TM10MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
170#define TM10MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 200#define TM10MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
171#define TM10MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 201#define TM10MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
202#if defined(CONFIG_AM33_2)
172#define TM10MD_SRC_TM10IO 0x07 /* - TM10IO pin input */ 203#define TM10MD_SRC_TM10IO 0x07 /* - TM10IO pin input */
204#else /* !CONFIG_AM33_2 */
205#define TM10MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
206#endif /* CONFIG_AM33_2 */
173#define TM10MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 207#define TM10MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
174#define TM10MD_COUNT_ENABLE 0x80 /* timer count enable */ 208#define TM10MD_COUNT_ENABLE 0x80 /* timer count enable */
175 209
@@ -178,32 +212,101 @@
178#define TM11MD_SRC_IOCLK 0x00 /* - IOCLK */ 212#define TM11MD_SRC_IOCLK 0x00 /* - IOCLK */
179#define TM11MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ 213#define TM11MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
180#define TM11MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ 214#define TM11MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
181#define TM11MD_SRC_TM7CASCADE 0x03 /* - cascade with timer 7 */
182#define TM11MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ 215#define TM11MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
183#define TM11MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ 216#define TM11MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
184#define TM11MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ 217#define TM11MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
218#if defined(CONFIG_AM33_2)
185#define TM11MD_SRC_TM11IO 0x07 /* - TM11IO pin input */ 219#define TM11MD_SRC_TM11IO 0x07 /* - TM11IO pin input */
220#else /* !CONFIG_AM33_2 */
221#define TM11MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
222#endif /* CONFIG_AM33_2 */
186#define TM11MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ 223#define TM11MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
187#define TM11MD_COUNT_ENABLE 0x80 /* timer count enable */ 224#define TM11MD_COUNT_ENABLE 0x80 /* timer count enable */
188 225
226#if defined(CONFIG_AM34_2)
227#define TM12MD __SYSREG(0xd4003180, u8) /* timer 11 mode register */
228#define TM12MD_SRC 0x07 /* timer source */
229#define TM12MD_SRC_IOCLK 0x00 /* - IOCLK */
230#define TM12MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
231#define TM12MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
232#define TM12MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
233#define TM12MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
234#define TM12MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
235#define TM12MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
236#define TM12MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
237#define TM12MD_COUNT_ENABLE 0x80 /* timer count enable */
238
239#define TM13MD __SYSREG(0xd4003182, u8) /* timer 11 mode register */
240#define TM13MD_SRC 0x07 /* timer source */
241#define TM13MD_SRC_IOCLK 0x00 /* - IOCLK */
242#define TM13MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
243#define TM13MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
244#define TM13MD_SRC_TM12CASCADE 0x03 /* - cascade with timer 12 */
245#define TM13MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
246#define TM13MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
247#define TM13MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
248#define TM13MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
249#define TM13MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
250#define TM13MD_COUNT_ENABLE 0x80 /* timer count enable */
251
252#define TM14MD __SYSREG(0xd4003184, u8) /* timer 11 mode register */
253#define TM14MD_SRC 0x07 /* timer source */
254#define TM14MD_SRC_IOCLK 0x00 /* - IOCLK */
255#define TM14MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
256#define TM14MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
257#define TM14MD_SRC_TM13CASCADE 0x03 /* - cascade with timer 13 */
258#define TM14MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
259#define TM14MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
260#define TM14MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
261#define TM14MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
262#define TM14MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
263#define TM14MD_COUNT_ENABLE 0x80 /* timer count enable */
264
265#define TM15MD __SYSREG(0xd4003186, u8) /* timer 11 mode register */
266#define TM15MD_SRC 0x07 /* timer source */
267#define TM15MD_SRC_IOCLK 0x00 /* - IOCLK */
268#define TM15MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */
269#define TM15MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */
270#define TM15MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */
271#define TM15MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */
272#define TM15MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */
273#define TM15MD_SRC_TM7UFLOW 0x07 /* - timer 7 underflow */
274#define TM15MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */
275#define TM15MD_COUNT_ENABLE 0x80 /* timer count enable */
276#endif /* CONFIG_AM34_2 */
277
278
189#define TM4BR __SYSREG(0xd4003090, u16) /* timer 4 base register */ 279#define TM4BR __SYSREG(0xd4003090, u16) /* timer 4 base register */
190#define TM5BR __SYSREG(0xd4003092, u16) /* timer 5 base register */ 280#define TM5BR __SYSREG(0xd4003092, u16) /* timer 5 base register */
281#define TM45BR __SYSREG(0xd4003090, u32) /* timer 4:5 base register */
191#define TM7BR __SYSREG(0xd4003096, u16) /* timer 7 base register */ 282#define TM7BR __SYSREG(0xd4003096, u16) /* timer 7 base register */
192#define TM8BR __SYSREG(0xd4003098, u16) /* timer 8 base register */ 283#define TM8BR __SYSREG(0xd4003098, u16) /* timer 8 base register */
193#define TM9BR __SYSREG(0xd400309a, u16) /* timer 9 base register */ 284#define TM9BR __SYSREG(0xd400309a, u16) /* timer 9 base register */
285#define TM89BR __SYSREG(0xd4003098, u32) /* timer 8:9 base register */
194#define TM10BR __SYSREG(0xd400309c, u16) /* timer 10 base register */ 286#define TM10BR __SYSREG(0xd400309c, u16) /* timer 10 base register */
195#define TM11BR __SYSREG(0xd400309e, u16) /* timer 11 base register */ 287#define TM11BR __SYSREG(0xd400309e, u16) /* timer 11 base register */
196#define TM45BR __SYSREG(0xd4003090, u32) /* timer 4:5 base register */ 288#if defined(CONFIG_AM34_2)
289#define TM12BR __SYSREG(0xd4003190, u16) /* timer 12 base register */
290#define TM13BR __SYSREG(0xd4003192, u16) /* timer 13 base register */
291#define TM14BR __SYSREG(0xd4003194, u16) /* timer 14 base register */
292#define TM15BR __SYSREG(0xd4003196, u16) /* timer 15 base register */
293#endif /* CONFIG_AM34_2 */
197 294
198#define TM4BC __SYSREG(0xd40030a0, u16) /* timer 4 binary counter */ 295#define TM4BC __SYSREG(0xd40030a0, u16) /* timer 4 binary counter */
199#define TM5BC __SYSREG(0xd40030a2, u16) /* timer 5 binary counter */ 296#define TM5BC __SYSREG(0xd40030a2, u16) /* timer 5 binary counter */
200#define TM45BC __SYSREG(0xd40030a0, u32) /* timer 4:5 binary counter */ 297#define TM45BC __SYSREG(0xd40030a0, u32) /* timer 4:5 binary counter */
201
202#define TM7BC __SYSREG(0xd40030a6, u16) /* timer 7 binary counter */ 298#define TM7BC __SYSREG(0xd40030a6, u16) /* timer 7 binary counter */
203#define TM8BC __SYSREG(0xd40030a8, u16) /* timer 8 binary counter */ 299#define TM8BC __SYSREG(0xd40030a8, u16) /* timer 8 binary counter */
204#define TM9BC __SYSREG(0xd40030aa, u16) /* timer 9 binary counter */ 300#define TM9BC __SYSREG(0xd40030aa, u16) /* timer 9 binary counter */
301#define TM89BC __SYSREG(0xd40030a8, u32) /* timer 8:9 binary counter */
205#define TM10BC __SYSREG(0xd40030ac, u16) /* timer 10 binary counter */ 302#define TM10BC __SYSREG(0xd40030ac, u16) /* timer 10 binary counter */
206#define TM11BC __SYSREG(0xd40030ae, u16) /* timer 11 binary counter */ 303#define TM11BC __SYSREG(0xd40030ae, u16) /* timer 11 binary counter */
304#if defined(CONFIG_AM34_2)
305#define TM12BC __SYSREG(0xd40031a0, u16) /* timer 12 binary counter */
306#define TM13BC __SYSREG(0xd40031a2, u16) /* timer 13 binary counter */
307#define TM14BC __SYSREG(0xd40031a4, u16) /* timer 14 binary counter */
308#define TM15BC __SYSREG(0xd40031a6, u16) /* timer 15 binary counter */
309#endif /* CONFIG_AM34_2 */
207 310
208#define TM4IRQ 6 /* timer 4 IRQ */ 311#define TM4IRQ 6 /* timer 4 IRQ */
209#define TM5IRQ 7 /* timer 5 IRQ */ 312#define TM5IRQ 7 /* timer 5 IRQ */
@@ -212,6 +315,12 @@
212#define TM9IRQ 13 /* timer 9 IRQ */ 315#define TM9IRQ 13 /* timer 9 IRQ */
213#define TM10IRQ 14 /* timer 10 IRQ */ 316#define TM10IRQ 14 /* timer 10 IRQ */
214#define TM11IRQ 15 /* timer 11 IRQ */ 317#define TM11IRQ 15 /* timer 11 IRQ */
318#if defined(CONFIG_AM34_2)
319#define TM12IRQ 64 /* timer 12 IRQ */
320#define TM13IRQ 65 /* timer 13 IRQ */
321#define TM14IRQ 66 /* timer 14 IRQ */
322#define TM15IRQ 67 /* timer 15 IRQ */
323#endif /* CONFIG_AM34_2 */
215 324
216#define TM4ICR GxICR(TM4IRQ) /* timer 4 uflow intr ctrl reg */ 325#define TM4ICR GxICR(TM4IRQ) /* timer 4 uflow intr ctrl reg */
217#define TM5ICR GxICR(TM5IRQ) /* timer 5 uflow intr ctrl reg */ 326#define TM5ICR GxICR(TM5IRQ) /* timer 5 uflow intr ctrl reg */
@@ -220,8 +329,16 @@
220#define TM9ICR GxICR(TM9IRQ) /* timer 9 uflow intr ctrl reg */ 329#define TM9ICR GxICR(TM9IRQ) /* timer 9 uflow intr ctrl reg */
221#define TM10ICR GxICR(TM10IRQ) /* timer 10 uflow intr ctrl reg */ 330#define TM10ICR GxICR(TM10IRQ) /* timer 10 uflow intr ctrl reg */
222#define TM11ICR GxICR(TM11IRQ) /* timer 11 uflow intr ctrl reg */ 331#define TM11ICR GxICR(TM11IRQ) /* timer 11 uflow intr ctrl reg */
223 332#if defined(CONFIG_AM34_2)
224/* 16-bit timer 6 */ 333#define TM12ICR GxICR(TM12IRQ) /* timer 12 uflow intr ctrl reg */
334#define TM13ICR GxICR(TM13IRQ) /* timer 13 uflow intr ctrl reg */
335#define TM14ICR GxICR(TM14IRQ) /* timer 14 uflow intr ctrl reg */
336#define TM15ICR GxICR(TM15IRQ) /* timer 15 uflow intr ctrl reg */
337#endif /* CONFIG_AM34_2 */
338
339/*
340 * 16-bit timer 6
341 */
225#define TM6MD __SYSREG(0xd4003084, u16) /* timer6 mode register */ 342#define TM6MD __SYSREG(0xd4003084, u16) /* timer6 mode register */
226#define TM6MD_SRC 0x0007 /* timer source */ 343#define TM6MD_SRC 0x0007 /* timer source */
227#define TM6MD_SRC_IOCLK 0x0000 /* - IOCLK */ 344#define TM6MD_SRC_IOCLK 0x0000 /* - IOCLK */
@@ -229,10 +346,14 @@
229#define TM6MD_SRC_IOCLK_32 0x0002 /* - 1/32 IOCLK */ 346#define TM6MD_SRC_IOCLK_32 0x0002 /* - 1/32 IOCLK */
230#define TM6MD_SRC_TM0UFLOW 0x0004 /* - timer 0 underflow */ 347#define TM6MD_SRC_TM0UFLOW 0x0004 /* - timer 0 underflow */
231#define TM6MD_SRC_TM1UFLOW 0x0005 /* - timer 1 underflow */ 348#define TM6MD_SRC_TM1UFLOW 0x0005 /* - timer 1 underflow */
232#define TM6MD_SRC_TM6IOB_BOTH 0x0006 /* - TM6IOB pin input (both edges) */ 349#define TM6MD_SRC_TM2UFLOW 0x0006 /* - timer 2 underflow */
350#if defined(CONFIG_AM33_2)
351/* #define TM6MD_SRC_TM6IOB_BOTH 0x0006 */ /* - TM6IOB pin input (both edges) */
233#define TM6MD_SRC_TM6IOB_SINGLE 0x0007 /* - TM6IOB pin input (single edge) */ 352#define TM6MD_SRC_TM6IOB_SINGLE 0x0007 /* - TM6IOB pin input (single edge) */
234#define TM6MD_CLR_ENABLE 0x0010 /* clear count enable */ 353#endif /* CONFIG_AM33_2 */
235#define TM6MD_ONESHOT_ENABLE 0x0040 /* oneshot count */ 354#define TM6MD_ONESHOT_ENABLE 0x0040 /* oneshot count */
355#define TM6MD_CLR_ENABLE 0x0010 /* clear count enable */
356#if defined(CONFIG_AM33_2)
236#define TM6MD_TRIG_ENABLE 0x0080 /* TM6IOB pin trigger enable */ 357#define TM6MD_TRIG_ENABLE 0x0080 /* TM6IOB pin trigger enable */
237#define TM6MD_PWM 0x3800 /* PWM output mode */ 358#define TM6MD_PWM 0x3800 /* PWM output mode */
238#define TM6MD_PWM_DIS 0x0000 /* - disabled */ 359#define TM6MD_PWM_DIS 0x0000 /* - disabled */
@@ -240,10 +361,15 @@
240#define TM6MD_PWM_11BIT 0x1800 /* - 11 bits mode */ 361#define TM6MD_PWM_11BIT 0x1800 /* - 11 bits mode */
241#define TM6MD_PWM_12BIT 0x3000 /* - 12 bits mode */ 362#define TM6MD_PWM_12BIT 0x3000 /* - 12 bits mode */
242#define TM6MD_PWM_14BIT 0x3800 /* - 14 bits mode */ 363#define TM6MD_PWM_14BIT 0x3800 /* - 14 bits mode */
364#endif /* CONFIG_AM33_2 */
365
243#define TM6MD_INIT_COUNTER 0x4000 /* initialize TMnBC to zero */ 366#define TM6MD_INIT_COUNTER 0x4000 /* initialize TMnBC to zero */
244#define TM6MD_COUNT_ENABLE 0x8000 /* timer count enable */ 367#define TM6MD_COUNT_ENABLE 0x8000 /* timer count enable */
245 368
246#define TM6MDA __SYSREG(0xd40030b4, u8) /* timer6 cmp/cap A mode reg */ 369#define TM6MDA __SYSREG(0xd40030b4, u8) /* timer6 cmp/cap A mode reg */
370#define TM6MDA_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
371#define TM6MDA_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
372#if defined(CONFIG_AM33_2)
247#define TM6MDA_OUT 0x07 /* output select */ 373#define TM6MDA_OUT 0x07 /* output select */
248#define TM6MDA_OUT_SETA_RESETB 0x00 /* - set at match A, reset at match B */ 374#define TM6MDA_OUT_SETA_RESETB 0x00 /* - set at match A, reset at match B */
249#define TM6MDA_OUT_SETA_RESETOV 0x01 /* - set at match A, reset at overflow */ 375#define TM6MDA_OUT_SETA_RESETOV 0x01 /* - set at match A, reset at overflow */
@@ -251,30 +377,35 @@
251#define TM6MDA_OUT_RESETA 0x03 /* - reset at match A */ 377#define TM6MDA_OUT_RESETA 0x03 /* - reset at match A */
252#define TM6MDA_OUT_TOGGLE 0x04 /* - toggle on match A */ 378#define TM6MDA_OUT_TOGGLE 0x04 /* - toggle on match A */
253#define TM6MDA_MODE 0xc0 /* compare A register mode */ 379#define TM6MDA_MODE 0xc0 /* compare A register mode */
254#define TM6MDA_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
255#define TM6MDA_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
256#define TM6MDA_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */ 380#define TM6MDA_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */
257#define TM6MDA_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */ 381#define TM6MDA_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */
258#define TM6MDA_EDGE 0x20 /* compare A edge select */ 382#define TM6MDA_EDGE 0x20 /* compare A edge select */
259#define TM6MDA_EDGE_FALLING 0x00 /* capture on falling edge */ 383#define TM6MDA_EDGE_FALLING 0x00 /* capture on falling edge */
260#define TM6MDA_EDGE_RISING 0x20 /* capture on rising edge */ 384#define TM6MDA_EDGE_RISING 0x20 /* capture on rising edge */
261#define TM6MDA_CAPTURE_ENABLE 0x10 /* capture enable */ 385#define TM6MDA_CAPTURE_ENABLE 0x10 /* capture enable */
386#else /* !CONFIG_AM33_2 */
387#define TM6MDA_MODE 0x40 /* compare A register mode */
388#endif /* CONFIG_AM33_2 */
262 389
263#define TM6MDB __SYSREG(0xd40030b5, u8) /* timer6 cmp/cap B mode reg */ 390#define TM6MDB __SYSREG(0xd40030b5, u8) /* timer6 cmp/cap B mode reg */
391#define TM6MDB_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
392#define TM6MDB_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
393#if defined(CONFIG_AM33_2)
264#define TM6MDB_OUT 0x07 /* output select */ 394#define TM6MDB_OUT 0x07 /* output select */
265#define TM6MDB_OUT_SETB_RESETA 0x00 /* - set at match B, reset at match A */ 395#define TM6MDB_OUT_SETB_RESETA 0x00 /* - set at match B, reset at match A */
266#define TM6MDB_OUT_SETB_RESETOV 0x01 /* - set at match B */ 396#define TM6MDB_OUT_SETB_RESETOV 0x01 /* - set at match B */
267#define TM6MDB_OUT_RESETB 0x03 /* - reset at match B */ 397#define TM6MDB_OUT_RESETB 0x03 /* - reset at match B */
268#define TM6MDB_OUT_TOGGLE 0x04 /* - toggle on match B */ 398#define TM6MDB_OUT_TOGGLE 0x04 /* - toggle on match B */
269#define TM6MDB_MODE 0xc0 /* compare B register mode */ 399#define TM6MDB_MODE 0xc0 /* compare B register mode */
270#define TM6MDB_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */
271#define TM6MDB_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */
272#define TM6MDB_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */ 400#define TM6MDB_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */
273#define TM6MDB_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */ 401#define TM6MDB_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */
274#define TM6MDB_EDGE 0x20 /* compare B edge select */ 402#define TM6MDB_EDGE 0x20 /* compare B edge select */
275#define TM6MDB_EDGE_FALLING 0x00 /* capture on falling edge */ 403#define TM6MDB_EDGE_FALLING 0x00 /* capture on falling edge */
276#define TM6MDB_EDGE_RISING 0x20 /* capture on rising edge */ 404#define TM6MDB_EDGE_RISING 0x20 /* capture on rising edge */
277#define TM6MDB_CAPTURE_ENABLE 0x10 /* capture enable */ 405#define TM6MDB_CAPTURE_ENABLE 0x10 /* capture enable */
406#else /* !CONFIG_AM33_2 */
407#define TM6MDB_MODE 0x40 /* compare B register mode */
408#endif /* CONFIG_AM33_2 */
278 409
279#define TM6CA __SYSREG(0xd40030c4, u16) /* timer6 cmp/capture reg A */ 410#define TM6CA __SYSREG(0xd40030c4, u16) /* timer6 cmp/capture reg A */
280#define TM6CB __SYSREG(0xd40030d4, u16) /* timer6 cmp/capture reg B */ 411#define TM6CB __SYSREG(0xd40030d4, u16) /* timer6 cmp/capture reg B */
@@ -288,6 +419,34 @@
288#define TM6AICR GxICR(TM6AIRQ) /* timer 6A intr control reg */ 419#define TM6AICR GxICR(TM6AIRQ) /* timer 6A intr control reg */
289#define TM6BICR GxICR(TM6BIRQ) /* timer 6B intr control reg */ 420#define TM6BICR GxICR(TM6BIRQ) /* timer 6B intr control reg */
290 421
422#if defined(CONFIG_AM34_2)
423/*
424 * MTM: OS Tick-Timer
425 */
426#define TMTMD __SYSREG(0xd4004100, u8) /* Tick Timer mode register */
427#define TMTMD_TMTLDE 0x40 /* initialize TMTBC = TMTBR */
428#define TMTMD_TMTCNE 0x80 /* timer count enable */
429
430#define TMTBR __SYSREG(0xd4004110, u32) /* Tick Timer mode reg */
431#define TMTBC __SYSREG(0xd4004120, u32) /* Tick Timer mode reg */
432
433/*
434 * MTM: OS Timestamp-Timer
435 */
436#define TMSMD __SYSREG(0xd4004140, u8) /* Tick Timer mode register */
437#define TMSMD_TMSLDE 0x40 /* initialize TMSBC = TMSBR */
438#define TMSMD_TMSCNE 0x80 /* timer count enable */
439
440#define TMSBR __SYSREG(0xd4004150, u32) /* Tick Timer mode register */
441#define TMSBC __SYSREG(0xd4004160, u32) /* Tick Timer mode register */
442
443#define TMTIRQ 119 /* OS Tick timer IRQ */
444#define TMSIRQ 120 /* Timestamp timer IRQ */
445
446#define TMTICR GxICR(TMTIRQ) /* OS Tick timer uflow intr ctrl reg */
447#define TMSICR GxICR(TMSIRQ) /* Timestamp timer uflow intr ctrl reg */
448#endif /* CONFIG_AM34_2 */
449
291#endif /* __KERNEL__ */ 450#endif /* __KERNEL__ */
292 451
293#endif /* _ASM_TIMER_REGS_H */ 452#endif /* _ASM_TIMER_REGS_H */
diff --git a/arch/mn10300/include/asm/timex.h b/arch/mn10300/include/asm/timex.h
index 8d031f9e117d..ce5719a2ce7c 100644
--- a/arch/mn10300/include/asm/timex.h
+++ b/arch/mn10300/include/asm/timex.h
@@ -16,8 +16,7 @@
16 16
17#define TICK_SIZE (tick_nsec / 1000) 17#define TICK_SIZE (tick_nsec / 1000)
18 18
19#define CLOCK_TICK_RATE 1193180 /* Underlying HZ - this should probably be set 19#define CLOCK_TICK_RATE MN10300_JCCLK /* Underlying HZ */
20 * to something appropriate, but what? */
21 20
22extern cycles_t cacheflush_time; 21extern cycles_t cacheflush_time;
23 22
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h
index 197a7af3dd8a..47e7951e6893 100644
--- a/arch/mn10300/include/asm/uaccess.h
+++ b/arch/mn10300/include/asm/uaccess.h
@@ -377,7 +377,7 @@ unsigned long __generic_copy_to_user_nocheck(void *to, const void *from,
377 377
378 378
379#if 0 379#if 0
380#error don't use - these macros don't increment to & from pointers 380#error "don't use - these macros don't increment to & from pointers"
381/* Optimize just a little bit when we know the size of the move. */ 381/* Optimize just a little bit when we know the size of the move. */
382#define __constant_copy_user(to, from, size) \ 382#define __constant_copy_user(to, from, size) \
383do { \ 383do { \
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
index 99022351717a..5b41192f496b 100644
--- a/arch/mn10300/kernel/Makefile
+++ b/arch/mn10300/kernel/Makefile
@@ -10,8 +10,9 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
10 ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ 10 ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \
11 switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) 11 switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y)
12 12
13obj-$(CONFIG_MN10300_WD_TIMER) += mn10300-watchdog.o mn10300-watchdog-low.o 13obj-$(CONFIG_SMP) += smp.o smp-low.o
14 14
15obj-$(CONFIG_MN10300_WD_TIMER) += mn10300-watchdog.o mn10300-watchdog-low.o
15 16
16obj-$(CONFIG_MN10300_TTYSM) += mn10300-serial.o mn10300-serial-low.o \ 17obj-$(CONFIG_MN10300_TTYSM) += mn10300-serial.o mn10300-serial-low.o \
17 mn10300-debug.o 18 mn10300-debug.o
diff --git a/arch/mn10300/kernel/asm-offsets.c b/arch/mn10300/kernel/asm-offsets.c
index 78e290e342fc..54cc5b6b13f2 100644
--- a/arch/mn10300/kernel/asm-offsets.c
+++ b/arch/mn10300/kernel/asm-offsets.c
@@ -66,7 +66,7 @@ void foo(void)
66 OFFSET(THREAD_SP, thread_struct, sp); 66 OFFSET(THREAD_SP, thread_struct, sp);
67 OFFSET(THREAD_A3, thread_struct, a3); 67 OFFSET(THREAD_A3, thread_struct, a3);
68 OFFSET(THREAD_USP, thread_struct, usp); 68 OFFSET(THREAD_USP, thread_struct, usp);
69 OFFSET(THREAD_FRAME, thread_struct, __frame); 69 OFFSET(THREAD_FRAME, thread_struct, frame);
70#ifdef CONFIG_FPU 70#ifdef CONFIG_FPU
71 OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags); 71 OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags);
72 OFFSET(THREAD_FPU_STATE, thread_struct, fpu_state); 72 OFFSET(THREAD_FPU_STATE, thread_struct, fpu_state);
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index 355f68176771..f00b9bafcd3e 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -28,25 +28,17 @@
28#include <asm/asm-offsets.h> 28#include <asm/asm-offsets.h>
29#include <asm/frame.inc> 29#include <asm/frame.inc>
30 30
31#if defined(CONFIG_SMP) && defined(CONFIG_GDBSTUB)
32#include <asm/gdb-stub.h>
33#endif /* CONFIG_SMP && CONFIG_GDBSTUB */
34
31#ifdef CONFIG_PREEMPT 35#ifdef CONFIG_PREEMPT
32#define preempt_stop __cli 36#define preempt_stop LOCAL_IRQ_DISABLE
33#else 37#else
34#define preempt_stop 38#define preempt_stop
35#define resume_kernel restore_all 39#define resume_kernel restore_all
36#endif 40#endif
37 41
38 .macro __cli
39 and ~EPSW_IM,epsw
40 or EPSW_IE|MN10300_CLI_LEVEL,epsw
41 nop
42 nop
43 nop
44 .endm
45 .macro __sti
46 or EPSW_IE|EPSW_IM_7,epsw
47 .endm
48
49
50 .am33_2 42 .am33_2
51 43
52############################################################################### 44###############################################################################
@@ -88,7 +80,7 @@ syscall_call:
88syscall_exit: 80syscall_exit:
89 # make sure we don't miss an interrupt setting need_resched or 81 # make sure we don't miss an interrupt setting need_resched or
90 # sigpending between sampling and the rti 82 # sigpending between sampling and the rti
91 __cli 83 LOCAL_IRQ_DISABLE
92 mov (TI_flags,a2),d2 84 mov (TI_flags,a2),d2
93 btst _TIF_ALLWORK_MASK,d2 85 btst _TIF_ALLWORK_MASK,d2
94 bne syscall_exit_work 86 bne syscall_exit_work
@@ -105,7 +97,7 @@ restore_all:
105syscall_exit_work: 97syscall_exit_work:
106 btst _TIF_SYSCALL_TRACE,d2 98 btst _TIF_SYSCALL_TRACE,d2
107 beq work_pending 99 beq work_pending
108 __sti # could let syscall_trace_exit() call 100 LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call
109 # schedule() instead 101 # schedule() instead
110 mov fp,d0 102 mov fp,d0
111 call syscall_trace_exit[],0 # do_syscall_trace(regs) 103 call syscall_trace_exit[],0 # do_syscall_trace(regs)
@@ -121,7 +113,7 @@ work_resched:
121 113
122 # make sure we don't miss an interrupt setting need_resched or 114 # make sure we don't miss an interrupt setting need_resched or
123 # sigpending between sampling and the rti 115 # sigpending between sampling and the rti
124 __cli 116 LOCAL_IRQ_DISABLE
125 117
126 # is there any work to be done other than syscall tracing? 118 # is there any work to be done other than syscall tracing?
127 mov (TI_flags,a2),d2 119 mov (TI_flags,a2),d2
@@ -168,7 +160,7 @@ ret_from_intr:
168ENTRY(resume_userspace) 160ENTRY(resume_userspace)
169 # make sure we don't miss an interrupt setting need_resched or 161 # make sure we don't miss an interrupt setting need_resched or
170 # sigpending between sampling and the rti 162 # sigpending between sampling and the rti
171 __cli 163 LOCAL_IRQ_DISABLE
172 164
173 # is there any work to be done on int/exception return? 165 # is there any work to be done on int/exception return?
174 mov (TI_flags,a2),d2 166 mov (TI_flags,a2),d2
@@ -178,7 +170,7 @@ ENTRY(resume_userspace)
178 170
179#ifdef CONFIG_PREEMPT 171#ifdef CONFIG_PREEMPT
180ENTRY(resume_kernel) 172ENTRY(resume_kernel)
181 __cli 173 LOCAL_IRQ_DISABLE
182 mov (TI_preempt_count,a2),d0 # non-zero preempt_count ? 174 mov (TI_preempt_count,a2),d0 # non-zero preempt_count ?
183 cmp 0,d0 175 cmp 0,d0
184 bne restore_all 176 bne restore_all
@@ -281,6 +273,79 @@ ENTRY(nmi_handler)
281 add -4,sp 273 add -4,sp
282 mov d0,(sp) 274 mov d0,(sp)
283 mov (TBR),d0 275 mov (TBR),d0
276
277#ifdef CONFIG_SMP
278 add -4,sp
279 mov d0,(sp) # save d0(TBR)
280 movhu (NMIAGR),d0
281 and NMIAGR_GN,d0
282 lsr 0x2,d0
283 cmp CALL_FUNCTION_NMI_IPI,d0
284 bne 5f # if not call function, jump
285
286 # function call nmi ipi
287 add 4,sp # no need to store TBR
288 mov GxICR_DETECT,d0 # clear NMI request
289 movbu d0,(GxICR(CALL_FUNCTION_NMI_IPI))
290 movhu (GxICR(CALL_FUNCTION_NMI_IPI)),d0
291 and ~EPSW_NMID,epsw # enable NMI
292
293 mov (sp),d0 # restore d0
294 SAVE_ALL
295 call smp_nmi_call_function_interrupt[],0
296 RESTORE_ALL
297
2985:
299#ifdef CONFIG_GDBSTUB
300 cmp GDB_NMI_IPI,d0
301 bne 3f # if not gdb nmi ipi, jump
302
303 # gdb nmi ipi
304 add 4,sp # no need to store TBR
305 mov GxICR_DETECT,d0 # clear NMI
306 movbu d0,(GxICR(GDB_NMI_IPI))
307 movhu (GxICR(GDB_NMI_IPI)),d0
308 and ~EPSW_NMID,epsw # enable NMI
309#ifdef CONFIG_MN10300_CACHE_ENABLED
310 mov (gdbstub_nmi_opr_type),d0
311 cmp GDBSTUB_NMI_CACHE_PURGE,d0
312 bne 4f # if not gdb cache purge, jump
313
314 # gdb cache purge nmi ipi
315 add -20,sp
316 mov d1,(4,sp)
317 mov a0,(8,sp)
318 mov a1,(12,sp)
319 mov mdr,d0
320 mov d0,(16,sp)
321 call gdbstub_local_purge_cache[],0
322 mov 0x1,d0
323 mov (CPUID),d1
324 asl d1,d0
325 mov gdbstub_nmi_cpumask,a0
326 bclr d0,(a0)
327 mov (4,sp),d1
328 mov (8,sp),a0
329 mov (12,sp),a1
330 mov (16,sp),d0
331 mov d0,mdr
332 add 20,sp
333 mov (sp),d0
334 add 4,sp
335 rti
3364:
337#endif /* CONFIG_MN10300_CACHE_ENABLED */
338 # gdb wait nmi ipi
339 mov (sp),d0
340 SAVE_ALL
341 call gdbstub_nmi_wait[],0
342 RESTORE_ALL
3433:
344#endif /* CONFIG_GDBSTUB */
345 mov (sp),d0 # restore TBR to d0
346 add 4,sp
347#endif /* CONFIG_SMP */
348
284 bra __common_exception_nonmi 349 bra __common_exception_nonmi
285 350
286ENTRY(__common_exception) 351ENTRY(__common_exception)
@@ -314,15 +379,21 @@ __common_exception_nonmi:
314 mov d0,(REG_ORIG_D0,fp) 379 mov d0,(REG_ORIG_D0,fp)
315 380
316#ifdef CONFIG_GDBSTUB 381#ifdef CONFIG_GDBSTUB
382#ifdef CONFIG_SMP
383 call gdbstub_busy_check[],0
384 and d0,d0 # check return value
385 beq 2f
386#else /* CONFIG_SMP */
317 btst 0x01,(gdbstub_busy) 387 btst 0x01,(gdbstub_busy)
318 beq 2f 388 beq 2f
389#endif /* CONFIG_SMP */
319 and ~EPSW_IE,epsw 390 and ~EPSW_IE,epsw
320 mov fp,d0 391 mov fp,d0
321 mov a2,d1 392 mov a2,d1
322 call gdbstub_exception[],0 # gdbstub itself caused an exception 393 call gdbstub_exception[],0 # gdbstub itself caused an exception
323 bra restore_all 394 bra restore_all
3242: 3952:
325#endif 396#endif /* CONFIG_GDBSTUB */
326 397
327 mov fp,d0 # arg 0: stacked register file 398 mov fp,d0 # arg 0: stacked register file
328 mov a2,d1 # arg 1: exception number 399 mov a2,d1 # arg 1: exception number
@@ -357,11 +428,7 @@ ENTRY(set_excp_vector)
357 add exception_table,d0 428 add exception_table,d0
358 mov d1,(d0) 429 mov d1,(d0)
359 mov 4,d1 430 mov 4,d1
360#if defined(CONFIG_MN10300_CACHE_WBACK)
361 jmp mn10300_dcache_flush_inv_range2
362#else
363 ret [],0 431 ret [],0
364#endif
365 432
366############################################################################### 433###############################################################################
367# 434#
diff --git a/arch/mn10300/kernel/gdb-io-serial-low.S b/arch/mn10300/kernel/gdb-io-serial-low.S
index 4998b24f5d3a..b1d0152e96cb 100644
--- a/arch/mn10300/kernel/gdb-io-serial-low.S
+++ b/arch/mn10300/kernel/gdb-io-serial-low.S
@@ -18,6 +18,7 @@
18#include <asm/thread_info.h> 18#include <asm/thread_info.h>
19#include <asm/frame.inc> 19#include <asm/frame.inc>
20#include <asm/intctl-regs.h> 20#include <asm/intctl-regs.h>
21#include <asm/irqflags.h>
21#include <unit/serial.h> 22#include <unit/serial.h>
22 23
23 .text 24 .text
@@ -69,7 +70,7 @@ gdbstub_io_rx_overflow:
69 bra gdbstub_io_rx_done 70 bra gdbstub_io_rx_done
70 71
71gdbstub_io_rx_enter: 72gdbstub_io_rx_enter:
72 or EPSW_IE|EPSW_IM_1,epsw 73 LOCAL_CHANGE_INTR_MASK_LEVEL(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL+1))
73 add -4,sp 74 add -4,sp
74 SAVE_ALL 75 SAVE_ALL
75 76
@@ -80,7 +81,7 @@ gdbstub_io_rx_enter:
80 mov fp,d0 81 mov fp,d0
81 call gdbstub_rx_irq[],0 # gdbstub_rx_irq(regs,excep) 82 call gdbstub_rx_irq[],0 # gdbstub_rx_irq(regs,excep)
82 83
83 and ~EPSW_IE,epsw 84 LOCAL_CLI
84 bclr 0x01,(gdbstub_busy) 85 bclr 0x01,(gdbstub_busy)
85 86
86 .globl gdbstub_return 87 .globl gdbstub_return
diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c
index ae663dc717e9..0d5d63c91dc3 100644
--- a/arch/mn10300/kernel/gdb-io-serial.c
+++ b/arch/mn10300/kernel/gdb-io-serial.c
@@ -23,6 +23,7 @@
23#include <asm/exceptions.h> 23#include <asm/exceptions.h>
24#include <asm/serial-regs.h> 24#include <asm/serial-regs.h>
25#include <unit/serial.h> 25#include <unit/serial.h>
26#include <asm/smp.h>
26 27
27/* 28/*
28 * initialise the GDB stub 29 * initialise the GDB stub
@@ -45,22 +46,34 @@ void gdbstub_io_init(void)
45 XIRQxICR(GDBPORT_SERIAL_IRQ) = 0; 46 XIRQxICR(GDBPORT_SERIAL_IRQ) = 0;
46 tmp = XIRQxICR(GDBPORT_SERIAL_IRQ); 47 tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
47 48
49#if CONFIG_GDBSTUB_IRQ_LEVEL == 0
48 IVAR0 = EXCEP_IRQ_LEVEL0; 50 IVAR0 = EXCEP_IRQ_LEVEL0;
49 set_intr_stub(EXCEP_IRQ_LEVEL0, gdbstub_io_rx_handler); 51#elif CONFIG_GDBSTUB_IRQ_LEVEL == 1
52 IVAR1 = EXCEP_IRQ_LEVEL1;
53#elif CONFIG_GDBSTUB_IRQ_LEVEL == 2
54 IVAR2 = EXCEP_IRQ_LEVEL2;
55#elif CONFIG_GDBSTUB_IRQ_LEVEL == 3
56 IVAR3 = EXCEP_IRQ_LEVEL3;
57#elif CONFIG_GDBSTUB_IRQ_LEVEL == 4
58 IVAR4 = EXCEP_IRQ_LEVEL4;
59#elif CONFIG_GDBSTUB_IRQ_LEVEL == 5
60 IVAR5 = EXCEP_IRQ_LEVEL5;
61#else
62#error "Unknown irq level for gdbstub."
63#endif
64
65 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL),
66 gdbstub_io_rx_handler);
50 67
51 XIRQxICR(GDBPORT_SERIAL_IRQ) &= ~GxICR_REQUEST; 68 XIRQxICR(GDBPORT_SERIAL_IRQ) &= ~GxICR_REQUEST;
52 XIRQxICR(GDBPORT_SERIAL_IRQ) = GxICR_ENABLE | GxICR_LEVEL_0; 69 XIRQxICR(GDBPORT_SERIAL_IRQ) =
70 GxICR_ENABLE | NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL);
53 tmp = XIRQxICR(GDBPORT_SERIAL_IRQ); 71 tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
54 72
55 GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI; 73 GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI;
56 74
57 /* permit level 0 IRQs to take place */ 75 /* permit level 0 IRQs to take place */
58 asm volatile( 76 local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
59 " and %0,epsw \n"
60 " or %1,epsw \n"
61 :
62 : "i"(~EPSW_IM), "i"(EPSW_IE | EPSW_IM_1)
63 );
64} 77}
65 78
66/* 79/*
@@ -87,6 +100,9 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
87{ 100{
88 unsigned ix; 101 unsigned ix;
89 u8 ch, st; 102 u8 ch, st;
103#if defined(CONFIG_MN10300_WD_TIMER)
104 int cpu;
105#endif
90 106
91 *_ch = 0xff; 107 *_ch = 0xff;
92 108
@@ -104,8 +120,9 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
104 if (nonblock) 120 if (nonblock)
105 return -EAGAIN; 121 return -EAGAIN;
106#ifdef CONFIG_MN10300_WD_TIMER 122#ifdef CONFIG_MN10300_WD_TIMER
107 watchdog_alert_counter = 0; 123 for (cpu = 0; cpu < NR_CPUS; cpu++)
108#endif /* CONFIG_MN10300_WD_TIMER */ 124 watchdog_alert_counter[cpu] = 0;
125#endif
109 goto try_again; 126 goto try_again;
110 } 127 }
111 128
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
index a560bbc3137d..97dfda23342c 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ b/arch/mn10300/kernel/gdb-io-ttysm.c
@@ -58,9 +58,12 @@ void __init gdbstub_io_init(void)
58 gdbstub_io_set_baud(115200); 58 gdbstub_io_set_baud(115200);
59 59
60 /* we want to get serial receive interrupts */ 60 /* we want to get serial receive interrupts */
61 set_intr_level(gdbstub_port->rx_irq, GxICR_LEVEL_0); 61 set_intr_level(gdbstub_port->rx_irq,
62 set_intr_level(gdbstub_port->tx_irq, GxICR_LEVEL_0); 62 NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL));
63 set_intr_stub(EXCEP_IRQ_LEVEL0, gdbstub_io_rx_handler); 63 set_intr_level(gdbstub_port->tx_irq,
64 NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL));
65 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL),
66 gdbstub_io_rx_handler);
64 67
65 *gdbstub_port->rx_icr |= GxICR_ENABLE; 68 *gdbstub_port->rx_icr |= GxICR_ENABLE;
66 tmp = *gdbstub_port->rx_icr; 69 tmp = *gdbstub_port->rx_icr;
@@ -84,12 +87,7 @@ void __init gdbstub_io_init(void)
84 tmp = *gdbstub_port->_control; 87 tmp = *gdbstub_port->_control;
85 88
86 /* permit level 0 IRQs only */ 89 /* permit level 0 IRQs only */
87 asm volatile( 90 local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
88 " and %0,epsw \n"
89 " or %1,epsw \n"
90 :
91 : "i"(~EPSW_IM), "i"(EPSW_IE|EPSW_IM_1)
92 );
93} 91}
94 92
95/* 93/*
@@ -184,6 +182,9 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
184{ 182{
185 unsigned ix; 183 unsigned ix;
186 u8 ch, st; 184 u8 ch, st;
185#if defined(CONFIG_MN10300_WD_TIMER)
186 int cpu;
187#endif
187 188
188 *_ch = 0xff; 189 *_ch = 0xff;
189 190
@@ -201,8 +202,9 @@ try_again:
201 if (nonblock) 202 if (nonblock)
202 return -EAGAIN; 203 return -EAGAIN;
203#ifdef CONFIG_MN10300_WD_TIMER 204#ifdef CONFIG_MN10300_WD_TIMER
204 watchdog_alert_counter = 0; 205 for (cpu = 0; cpu < NR_CPUS; cpu++)
205#endif /* CONFIG_MN10300_WD_TIMER */ 206 watchdog_alert_counter[cpu] = 0;
207#endif
206 goto try_again; 208 goto try_again;
207 } 209 }
208 210
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
index 41b11706c8ed..a5fc3f05309b 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -440,15 +440,11 @@ static const unsigned char gdbstub_insn_sizes[256] =
440 440
441static int __gdbstub_mark_bp(u8 *addr, int ix) 441static int __gdbstub_mark_bp(u8 *addr, int ix)
442{ 442{
443 if (addr < (u8 *) 0x70000000UL) 443 /* vmalloc area */
444 return 0; 444 if (((u8 *) VMALLOC_START <= addr) && (addr < (u8 *) VMALLOC_END))
445 /* 70000000-7fffffff: vmalloc area */
446 if (addr < (u8 *) 0x80000000UL)
447 goto okay; 445 goto okay;
448 if (addr < (u8 *) 0x8c000000UL) 446 /* SRAM, SDRAM */
449 return 0; 447 if (((u8 *) 0x80000000UL <= addr) && (addr < (u8 *) 0xa0000000UL))
450 /* 8c000000-93ffffff: SRAM, SDRAM */
451 if (addr < (u8 *) 0x94000000UL)
452 goto okay; 448 goto okay;
453 return 0; 449 return 0;
454 450
@@ -1197,9 +1193,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1197 mn10300_set_gdbleds(1); 1193 mn10300_set_gdbleds(1);
1198 1194
1199 asm volatile("mov mdr,%0" : "=d"(mdr)); 1195 asm volatile("mov mdr,%0" : "=d"(mdr));
1200 asm volatile("mov epsw,%0" : "=d"(epsw)); 1196 local_save_flags(epsw);
1201 asm volatile("mov %0,epsw" 1197 local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
1202 :: "d"((epsw & ~EPSW_IM) | EPSW_IE | EPSW_IM_1));
1203 1198
1204 gdbstub_store_fpu(); 1199 gdbstub_store_fpu();
1205 1200
diff --git a/arch/mn10300/kernel/head.S b/arch/mn10300/kernel/head.S
index a81e34fba651..73e00fc78072 100644
--- a/arch/mn10300/kernel/head.S
+++ b/arch/mn10300/kernel/head.S
@@ -19,6 +19,12 @@
19#include <asm/frame.inc> 19#include <asm/frame.inc>
20#include <asm/param.h> 20#include <asm/param.h>
21#include <unit/serial.h> 21#include <unit/serial.h>
22#ifdef CONFIG_SMP
23#include <asm/smp.h>
24#include <asm/intctl-regs.h>
25#include <asm/cpu-regs.h>
26#include <proc/smp-regs.h>
27#endif /* CONFIG_SMP */
22 28
23 __HEAD 29 __HEAD
24 30
@@ -30,17 +36,51 @@
30 .globl _start 36 .globl _start
31 .type _start,@function 37 .type _start,@function
32_start: 38_start:
39#ifdef CONFIG_SMP
40 #
41 # If this is a secondary CPU (AP), then deal with that elsewhere
42 #
43 mov (CPUID),d3
44 and CPUID_MASK,d3
45 bne startup_secondary
46
47 #
48 # We're dealing with the primary CPU (BP) here, then.
49 # Keep BP's D0,D1,D2 register for boot check.
50 #
51
52 # Set up the Boot IPI for each secondary CPU
53 mov 0x1,a0
54loop_set_secondary_icr:
55 mov a0,a1
56 asl CROSS_ICR_CPU_SHIFT,a1
57 add CROSS_GxICR(SMP_BOOT_IRQ,0),a1
58 movhu (a1),d3
59 or GxICR_ENABLE|GxICR_LEVEL_0,d3
60 movhu d3,(a1)
61 movhu (a1),d3 # flush
62 inc a0
63 cmp NR_CPUS,a0
64 bne loop_set_secondary_icr
65#endif /* CONFIG_SMP */
66
33 # save commandline pointer 67 # save commandline pointer
34 mov d0,a3 68 mov d0,a3
35 69
36 # preload the PGD pointer register 70 # preload the PGD pointer register
37 mov swapper_pg_dir,d0 71 mov swapper_pg_dir,d0
38 mov d0,(PTBR) 72 mov d0,(PTBR)
73 clr d0
74 movbu d0,(PIDR)
39 75
40 # turn on the TLBs 76 # turn on the TLBs
41 mov MMUCTR_IIV|MMUCTR_DIV,d0 77 mov MMUCTR_IIV|MMUCTR_DIV,d0
42 mov d0,(MMUCTR) 78 mov d0,(MMUCTR)
79#ifdef CONFIG_AM34_2
80 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
81#else
43 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0 82 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
83#endif
44 mov d0,(MMUCTR) 84 mov d0,(MMUCTR)
45 85
46 # turn on AM33v2 exception handling mode and set the trap table base 86 # turn on AM33v2 exception handling mode and set the trap table base
@@ -51,6 +91,11 @@ _start:
51 mov d0,(TBR) 91 mov d0,(TBR)
52 92
53 # invalidate and enable both of the caches 93 # invalidate and enable both of the caches
94#ifdef CONFIG_SMP
95 mov ECHCTR,a0
96 clr d0
97 mov d0,(a0)
98#endif
54 mov CHCTR,a0 99 mov CHCTR,a0
55 clr d0 100 clr d0
56 movhu d0,(a0) # turn off first 101 movhu d0,(a0) # turn off first
@@ -206,6 +251,44 @@ __no_parameters:
206 call processor_init[],0 251 call processor_init[],0
207 call unit_init[],0 252 call unit_init[],0
208 253
254#ifdef CONFIG_SMP
255 # mark the primary CPU in cpu_boot_map
256 mov cpu_boot_map,a0
257 mov 0x1,d0
258 mov d0,(a0)
259
260 # signal each secondary CPU to begin booting
261 mov 0x1,d2 # CPU ID
262
263loop_request_boot_secondary:
264 mov d2,a0
265 # send SMP_BOOT_IPI to secondary CPU
266 asl CROSS_ICR_CPU_SHIFT,a0
267 add CROSS_GxICR(SMP_BOOT_IRQ,0),a0
268 movhu (a0),d0
269 or GxICR_REQUEST|GxICR_DETECT,d0
270 movhu d0,(a0)
271 movhu (a0),d0 # flush
272
273 # wait up to 100ms for AP's IPI to be received
274 clr d3
275wait_on_secondary_boot:
276 mov DELAY_TIME_BOOT_IPI,d0
277 call __delay[],0
278 inc d3
279 mov cpu_boot_map,a0
280 mov (a0),d0
281 lsr d2,d0
282 btst 0x1,d0
283 bne 1f
284 cmp TIME_OUT_COUNT_BOOT_IPI,d3
285 bne wait_on_secondary_boot
2861:
287 inc d2
288 cmp NR_CPUS,d2
289 bne loop_request_boot_secondary
290#endif /* CONFIG_SMP */
291
209#ifdef CONFIG_GDBSTUB 292#ifdef CONFIG_GDBSTUB
210 call gdbstub_init[],0 293 call gdbstub_init[],0
211 294
@@ -217,7 +300,118 @@ __gdbstub_pause:
217#endif 300#endif
218 301
219 jmp start_kernel 302 jmp start_kernel
220 .size _start, _start-. 303 .size _start,.-_start
304
305###############################################################################
306#
307# Secondary CPU boot point
308#
309###############################################################################
310#ifdef CONFIG_SMP
311startup_secondary:
312 # preload the PGD pointer register
313 mov swapper_pg_dir,d0
314 mov d0,(PTBR)
315 clr d0
316 movbu d0,(PIDR)
317
318 # turn on the TLBs
319 mov MMUCTR_IIV|MMUCTR_DIV,d0
320 mov d0,(MMUCTR)
321#ifdef CONFIG_AM34_2
322 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
323#else
324 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
325#endif
326 mov d0,(MMUCTR)
327
328 # turn on AM33v2 exception handling mode and set the trap table base
329 movhu (CPUP),d0
330 or CPUP_EXM_AM33V2,d0
331 movhu d0,(CPUP)
332
333 # set the interrupt vector table
334 mov CONFIG_INTERRUPT_VECTOR_BASE,d0
335 mov d0,(TBR)
336
337 # invalidate and enable both of the caches
338 mov ECHCTR,a0
339 clr d0
340 mov d0,(a0)
341 mov CHCTR,a0
342 clr d0
343 movhu d0,(a0) # turn off first
344 mov CHCTR_ICINV|CHCTR_DCINV,d0
345 movhu d0,(a0)
346 setlb
347 mov (a0),d0
348 btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
349 lne
350
351#ifdef CONFIG_MN10300_CACHE_ENABLED
352#ifdef CONFIG_MN10300_CACHE_WBACK
353#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
354 mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
355#else
356 mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
357#endif /* !NOWRALLOC */
358#else
359 mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
360#endif /* WBACK */
361 movhu d0,(a0) # enable
362#endif /* ENABLED */
363
364 # Clear the boot IPI interrupt for this CPU
365 movhu (GxICR(SMP_BOOT_IRQ)),d0
366 and ~GxICR_REQUEST,d0
367 movhu d0,(GxICR(SMP_BOOT_IRQ))
368 movhu (GxICR(SMP_BOOT_IRQ)),d0 # flush
369
370 /* get stack */
371 mov CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
372 mov (CPUID),d0
373 and CPUID_MASK,d0
374 mulu CONFIG_BOOT_STACK_SIZE,d0
375 sub d0,a0
376 mov a0,sp
377
378 # init interrupt for AP
379 call smp_prepare_cpu_init[],0
380
381 # mark this secondary CPU in cpu_boot_map
382 mov (CPUID),d0
383 mov 0x1,d1
384 asl d0,d1
385 mov cpu_boot_map,a0
386 bset d1,(a0)
387
388 or EPSW_IE|EPSW_IM_1,epsw # permit level 0 interrupts
389 nop
390 nop
391#ifdef CONFIG_MN10300_CACHE_WBACK
392 # flush the local cache if it's in writeback mode
393 call mn10300_local_dcache_flush_inv[],0
394 setlb
395 mov (CHCTR),d0
396 btst CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
397 lne
398#endif
399
400 # now sleep waiting for further instructions
401secondary_sleep:
402 mov CPUM_SLEEP,d0
403 movhu d0,(CPUM)
404 nop
405 nop
406 bra secondary_sleep
407 .size startup_secondary,.-startup_secondary
408#endif /* CONFIG_SMP */
409
410###############################################################################
411#
412#
413#
414###############################################################################
221ENTRY(__head_end) 415ENTRY(__head_end)
222 416
223/* 417/*
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
index eee2eee86267..3b1f48b7e7f4 100644
--- a/arch/mn10300/kernel/internal.h
+++ b/arch/mn10300/kernel/internal.h
@@ -18,3 +18,15 @@ extern int kernel_thread_helper(int);
18 * entry.S 18 * entry.S
19 */ 19 */
20extern void ret_from_fork(struct task_struct *) __attribute__((noreturn)); 20extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
21
22/*
23 * smp-low.S
24 */
25#ifdef CONFIG_SMP
26extern void mn10300_low_ipi_handler(void);
27#endif
28
29/*
30 * time.c
31 */
32extern irqreturn_t local_timer_interrupt(void);
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index b5b970d2954a..80f15725ecad 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -12,11 +12,34 @@
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/kernel_stat.h> 13#include <linux/kernel_stat.h>
14#include <linux/seq_file.h> 14#include <linux/seq_file.h>
15#include <linux/cpumask.h>
15#include <asm/setup.h> 16#include <asm/setup.h>
17#include <asm/serial-regs.h>
16 18
17unsigned long __mn10300_irq_enabled_epsw = EPSW_IE | EPSW_IM_7; 19#ifdef CONFIG_SMP
20#undef GxICR
21#define GxICR(X) CROSS_GxICR(X, irq_affinity_online[X])
22
23#undef GxICR_u8
24#define GxICR_u8(X) CROSS_GxICR_u8(X, irq_affinity_online[X])
25#endif /* CONFIG_SMP */
26
27unsigned long __mn10300_irq_enabled_epsw[NR_CPUS] __cacheline_aligned_in_smp = {
28 [0 ... NR_CPUS - 1] = EPSW_IE | EPSW_IM_7
29};
18EXPORT_SYMBOL(__mn10300_irq_enabled_epsw); 30EXPORT_SYMBOL(__mn10300_irq_enabled_epsw);
19 31
32#ifdef CONFIG_SMP
33static char irq_affinity_online[NR_IRQS] = {
34 [0 ... NR_IRQS - 1] = 0
35};
36
37#define NR_IRQ_WORDS ((NR_IRQS + 31) / 32)
38static unsigned long irq_affinity_request[NR_IRQ_WORDS] = {
39 [0 ... NR_IRQ_WORDS - 1] = 0
40};
41#endif /* CONFIG_SMP */
42
20atomic_t irq_err_count; 43atomic_t irq_err_count;
21 44
22/* 45/*
@@ -24,30 +47,65 @@ atomic_t irq_err_count;
24 */ 47 */
25static void mn10300_cpupic_ack(unsigned int irq) 48static void mn10300_cpupic_ack(unsigned int irq)
26{ 49{
50 unsigned long flags;
51 u16 tmp;
52
53 flags = arch_local_cli_save();
54 GxICR_u8(irq) = GxICR_DETECT;
55 tmp = GxICR(irq);
56 arch_local_irq_restore(flags);
57}
58
59static void __mask_and_set_icr(unsigned int irq,
60 unsigned int mask, unsigned int set)
61{
62 unsigned long flags;
27 u16 tmp; 63 u16 tmp;
28 *(volatile u8 *) &GxICR(irq) = GxICR_DETECT; 64
65 flags = arch_local_cli_save();
29 tmp = GxICR(irq); 66 tmp = GxICR(irq);
67 GxICR(irq) = (tmp & mask) | set;
68 tmp = GxICR(irq);
69 arch_local_irq_restore(flags);
30} 70}
31 71
32static void mn10300_cpupic_mask(unsigned int irq) 72static void mn10300_cpupic_mask(unsigned int irq)
33{ 73{
34 u16 tmp = GxICR(irq); 74 __mask_and_set_icr(irq, GxICR_LEVEL, 0);
35 GxICR(irq) = (tmp & GxICR_LEVEL);
36 tmp = GxICR(irq);
37} 75}
38 76
39static void mn10300_cpupic_mask_ack(unsigned int irq) 77static void mn10300_cpupic_mask_ack(unsigned int irq)
40{ 78{
41 u16 tmp = GxICR(irq); 79#ifdef CONFIG_SMP
42 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT; 80 unsigned long flags;
43 tmp = GxICR(irq); 81 u16 tmp;
82
83 flags = arch_local_cli_save();
84
85 if (!test_and_clear_bit(irq, irq_affinity_request)) {
86 tmp = GxICR(irq);
87 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
88 tmp = GxICR(irq);
89 } else {
90 u16 tmp2;
91 tmp = GxICR(irq);
92 GxICR(irq) = (tmp & GxICR_LEVEL);
93 tmp2 = GxICR(irq);
94
95 irq_affinity_online[irq] = any_online_cpu(*irq_desc[irq].affinity);
96 GxICR(irq) = (tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT;
97 tmp = GxICR(irq);
98 }
99
100 arch_local_irq_restore(flags);
101#else /* CONFIG_SMP */
102 __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_DETECT);
103#endif /* CONFIG_SMP */
44} 104}
45 105
46static void mn10300_cpupic_unmask(unsigned int irq) 106static void mn10300_cpupic_unmask(unsigned int irq)
47{ 107{
48 u16 tmp = GxICR(irq); 108 __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_ENABLE);
49 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
50 tmp = GxICR(irq);
51} 109}
52 110
53static void mn10300_cpupic_unmask_clear(unsigned int irq) 111static void mn10300_cpupic_unmask_clear(unsigned int irq)
@@ -56,11 +114,89 @@ static void mn10300_cpupic_unmask_clear(unsigned int irq)
56 * device has ceased to assert its interrupt line and the interrupt 114 * device has ceased to assert its interrupt line and the interrupt
57 * channel has been disabled in the PIC, so for level-triggered 115 * channel has been disabled in the PIC, so for level-triggered
58 * interrupts we need to clear the request bit when we re-enable */ 116 * interrupts we need to clear the request bit when we re-enable */
59 u16 tmp = GxICR(irq); 117#ifdef CONFIG_SMP
60 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; 118 unsigned long flags;
61 tmp = GxICR(irq); 119 u16 tmp;
120
121 flags = arch_local_cli_save();
122
123 if (!test_and_clear_bit(irq, irq_affinity_request)) {
124 tmp = GxICR(irq);
125 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
126 tmp = GxICR(irq);
127 } else {
128 tmp = GxICR(irq);
129
130 irq_affinity_online[irq] = any_online_cpu(*irq_desc[irq].affinity);
131 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
132 tmp = GxICR(irq);
133 }
134
135 arch_local_irq_restore(flags);
136#else /* CONFIG_SMP */
137 __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_ENABLE | GxICR_DETECT);
138#endif /* CONFIG_SMP */
62} 139}
63 140
141#ifdef CONFIG_SMP
142static int
143mn10300_cpupic_setaffinity(unsigned int irq, const struct cpumask *mask)
144{
145 unsigned long flags;
146 int err;
147
148 flags = arch_local_cli_save();
149
150 /* check irq no */
151 switch (irq) {
152 case TMJCIRQ:
153 case RESCHEDULE_IPI:
154 case CALL_FUNC_SINGLE_IPI:
155 case LOCAL_TIMER_IPI:
156 case FLUSH_CACHE_IPI:
157 case CALL_FUNCTION_NMI_IPI:
158 case GDB_NMI_IPI:
159#ifdef CONFIG_MN10300_TTYSM0
160 case SC0RXIRQ:
161 case SC0TXIRQ:
162#ifdef CONFIG_MN10300_TTYSM0_TIMER8
163 case TM8IRQ:
164#elif CONFIG_MN10300_TTYSM0_TIMER2
165 case TM2IRQ:
166#endif /* CONFIG_MN10300_TTYSM0_TIMER8 */
167#endif /* CONFIG_MN10300_TTYSM0 */
168
169#ifdef CONFIG_MN10300_TTYSM1
170 case SC1RXIRQ:
171 case SC1TXIRQ:
172#ifdef CONFIG_MN10300_TTYSM1_TIMER12
173 case TM12IRQ:
174#elif CONFIG_MN10300_TTYSM1_TIMER9
175 case TM9IRQ:
176#elif CONFIG_MN10300_TTYSM1_TIMER3
177 case TM3IRQ:
178#endif /* CONFIG_MN10300_TTYSM1_TIMER12 */
179#endif /* CONFIG_MN10300_TTYSM1 */
180
181#ifdef CONFIG_MN10300_TTYSM2
182 case SC2RXIRQ:
183 case SC2TXIRQ:
184 case TM10IRQ:
185#endif /* CONFIG_MN10300_TTYSM2 */
186 err = -1;
187 break;
188
189 default:
190 set_bit(irq, irq_affinity_request);
191 err = 0;
192 break;
193 }
194
195 arch_local_irq_restore(flags);
196 return err;
197}
198#endif /* CONFIG_SMP */
199
64/* 200/*
65 * MN10300 PIC level-triggered IRQ handling. 201 * MN10300 PIC level-triggered IRQ handling.
66 * 202 *
@@ -79,6 +215,9 @@ static struct irq_chip mn10300_cpu_pic_level = {
79 .mask = mn10300_cpupic_mask, 215 .mask = mn10300_cpupic_mask,
80 .mask_ack = mn10300_cpupic_mask, 216 .mask_ack = mn10300_cpupic_mask,
81 .unmask = mn10300_cpupic_unmask_clear, 217 .unmask = mn10300_cpupic_unmask_clear,
218#ifdef CONFIG_SMP
219 .set_affinity = mn10300_cpupic_setaffinity,
220#endif /* CONFIG_SMP */
82}; 221};
83 222
84/* 223/*
@@ -94,6 +233,9 @@ static struct irq_chip mn10300_cpu_pic_edge = {
94 .mask = mn10300_cpupic_mask, 233 .mask = mn10300_cpupic_mask,
95 .mask_ack = mn10300_cpupic_mask_ack, 234 .mask_ack = mn10300_cpupic_mask_ack,
96 .unmask = mn10300_cpupic_unmask, 235 .unmask = mn10300_cpupic_unmask,
236#ifdef CONFIG_SMP
237 .set_affinity = mn10300_cpupic_setaffinity,
238#endif /* CONFIG_SMP */
97}; 239};
98 240
99/* 241/*
@@ -111,14 +253,34 @@ void ack_bad_irq(int irq)
111 */ 253 */
112void set_intr_level(int irq, u16 level) 254void set_intr_level(int irq, u16 level)
113{ 255{
114 u16 tmp; 256 BUG_ON(in_interrupt());
115 257
116 if (in_interrupt()) 258 __mask_and_set_icr(irq, GxICR_ENABLE, level);
117 BUG(); 259}
118 260
119 tmp = GxICR(irq); 261void mn10300_intc_set_level(unsigned int irq, unsigned int level)
120 GxICR(irq) = (tmp & GxICR_ENABLE) | level; 262{
121 tmp = GxICR(irq); 263 set_intr_level(irq, NUM2GxICR_LEVEL(level) & GxICR_LEVEL);
264}
265
266void mn10300_intc_clear(unsigned int irq)
267{
268 __mask_and_set_icr(irq, GxICR_LEVEL | GxICR_ENABLE, GxICR_DETECT);
269}
270
271void mn10300_intc_set(unsigned int irq)
272{
273 __mask_and_set_icr(irq, 0, GxICR_REQUEST | GxICR_DETECT);
274}
275
276void mn10300_intc_enable(unsigned int irq)
277{
278 mn10300_cpupic_unmask(irq);
279}
280
281void mn10300_intc_disable(unsigned int irq)
282{
283 mn10300_cpupic_mask(irq);
122} 284}
123 285
124/* 286/*
@@ -126,7 +288,7 @@ void set_intr_level(int irq, u16 level)
126 * than before 288 * than before
127 * - see Documentation/mn10300/features.txt 289 * - see Documentation/mn10300/features.txt
128 */ 290 */
129void set_intr_postackable(int irq) 291void mn10300_set_lateack_irq_type(int irq)
130{ 292{
131 set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level, 293 set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level,
132 handle_level_irq); 294 handle_level_irq);
@@ -147,6 +309,7 @@ void __init init_IRQ(void)
147 * interrupts */ 309 * interrupts */
148 set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge, 310 set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge,
149 handle_level_irq); 311 handle_level_irq);
312
150 unit_init_IRQ(); 313 unit_init_IRQ();
151} 314}
152 315
@@ -156,6 +319,7 @@ void __init init_IRQ(void)
156asmlinkage void do_IRQ(void) 319asmlinkage void do_IRQ(void)
157{ 320{
158 unsigned long sp, epsw, irq_disabled_epsw, old_irq_enabled_epsw; 321 unsigned long sp, epsw, irq_disabled_epsw, old_irq_enabled_epsw;
322 unsigned int cpu_id = smp_processor_id();
159 int irq; 323 int irq;
160 324
161 sp = current_stack_pointer(); 325 sp = current_stack_pointer();
@@ -163,12 +327,14 @@ asmlinkage void do_IRQ(void)
163 327
164 /* make sure local_irq_enable() doesn't muck up the interrupt priority 328 /* make sure local_irq_enable() doesn't muck up the interrupt priority
165 * setting in EPSW */ 329 * setting in EPSW */
166 old_irq_enabled_epsw = __mn10300_irq_enabled_epsw; 330 old_irq_enabled_epsw = __mn10300_irq_enabled_epsw[cpu_id];
167 local_save_flags(epsw); 331 local_save_flags(epsw);
168 __mn10300_irq_enabled_epsw = EPSW_IE | (EPSW_IM & epsw); 332 __mn10300_irq_enabled_epsw[cpu_id] = EPSW_IE | (EPSW_IM & epsw);
169 irq_disabled_epsw = EPSW_IE | MN10300_CLI_LEVEL; 333 irq_disabled_epsw = EPSW_IE | MN10300_CLI_LEVEL;
170 334
171 __IRQ_STAT(smp_processor_id(), __irq_count)++; 335#ifdef CONFIG_MN10300_WD_TIMER
336 __IRQ_STAT(cpu_id, __irq_count)++;
337#endif
172 338
173 irq_enter(); 339 irq_enter();
174 340
@@ -188,7 +354,7 @@ asmlinkage void do_IRQ(void)
188 local_irq_restore(epsw); 354 local_irq_restore(epsw);
189 } 355 }
190 356
191 __mn10300_irq_enabled_epsw = old_irq_enabled_epsw; 357 __mn10300_irq_enabled_epsw[cpu_id] = old_irq_enabled_epsw;
192 358
193 irq_exit(); 359 irq_exit();
194} 360}
@@ -239,11 +405,13 @@ int show_interrupts(struct seq_file *p, void *v)
239 405
240 /* polish off with NMI and error counters */ 406 /* polish off with NMI and error counters */
241 case NR_IRQS: 407 case NR_IRQS:
408#ifdef CONFIG_MN10300_WD_TIMER
242 seq_printf(p, "NMI: "); 409 seq_printf(p, "NMI: ");
243 for (j = 0; j < NR_CPUS; j++) 410 for (j = 0; j < NR_CPUS; j++)
244 if (cpu_online(j)) 411 if (cpu_online(j))
245 seq_printf(p, "%10u ", nmi_count(j)); 412 seq_printf(p, "%10u ", nmi_count(j));
246 seq_putc(p, '\n'); 413 seq_putc(p, '\n');
414#endif
247 415
248 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); 416 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
249 break; 417 break;
@@ -251,3 +419,51 @@ int show_interrupts(struct seq_file *p, void *v)
251 419
252 return 0; 420 return 0;
253} 421}
422
423#ifdef CONFIG_HOTPLUG_CPU
424void migrate_irqs(void)
425{
426 irq_desc_t *desc;
427 int irq;
428 unsigned int self, new;
429 unsigned long flags;
430
431 self = smp_processor_id();
432 for (irq = 0; irq < NR_IRQS; irq++) {
433 desc = irq_desc + irq;
434
435 if (desc->status == IRQ_PER_CPU)
436 continue;
437
438 if (cpu_isset(self, irq_desc[irq].affinity) &&
439 !cpus_intersects(irq_affinity[irq], cpu_online_map)) {
440 int cpu_id;
441 cpu_id = first_cpu(cpu_online_map);
442 cpu_set(cpu_id, irq_desc[irq].affinity);
443 }
444 /* We need to operate irq_affinity_online atomically. */
445 arch_local_cli_save(flags);
446 if (irq_affinity_online[irq] == self) {
447 u16 x, tmp;
448
449 x = CROSS_GxICR(irq, self);
450 CROSS_GxICR(irq, self) = x & GxICR_LEVEL;
451 tmp = CROSS_GxICR(irq, self);
452
453 new = any_online_cpu(irq_desc[irq].affinity);
454 irq_affinity_online[irq] = new;
455
456 CROSS_GxICR(irq, new) =
457 (x & GxICR_LEVEL) | GxICR_DETECT;
458 tmp = CROSS_GxICR(irq, new);
459
460 x &= GxICR_LEVEL | GxICR_ENABLE;
461 if (CROSS_GxICR(irq, self) & GxICR_REQUEST)
462 x |= GxICR_REQUEST | GxICR_DETECT;
463 CROSS_GxICR(irq, new) = x;
464 tmp = CROSS_GxICR(irq, new);
465 }
466 arch_local_irq_restore(flags);
467 }
468}
469#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mn10300/kernel/mn10300-serial-low.S b/arch/mn10300/kernel/mn10300-serial-low.S
index 66702d256610..dfc1b6f2fa9a 100644
--- a/arch/mn10300/kernel/mn10300-serial-low.S
+++ b/arch/mn10300/kernel/mn10300-serial-low.S
@@ -39,7 +39,7 @@
39############################################################################### 39###############################################################################
40 .balign L1_CACHE_BYTES 40 .balign L1_CACHE_BYTES
41ENTRY(mn10300_serial_vdma_interrupt) 41ENTRY(mn10300_serial_vdma_interrupt)
42 or EPSW_IE,psw # permit overriding by 42# or EPSW_IE,psw # permit overriding by
43 # debugging interrupts 43 # debugging interrupts
44 movm [d2,d3,a2,a3,exreg0],(sp) 44 movm [d2,d3,a2,a3,exreg0],(sp)
45 45
@@ -164,7 +164,7 @@ mnsc_vdma_tx_noint:
164 rti 164 rti
165 165
166mnsc_vdma_tx_empty: 166mnsc_vdma_tx_empty:
167 mov +(GxICR_LEVEL_1|GxICR_DETECT),d2 167 mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
168 movhu d2,(e3) # disable the interrupt 168 movhu d2,(e3) # disable the interrupt
169 movhu (e3),d2 # flush 169 movhu (e3),d2 # flush
170 170
@@ -175,7 +175,7 @@ mnsc_vdma_tx_break:
175 movhu (SCxCTR,e2),d2 # turn on break mode 175 movhu (SCxCTR,e2),d2 # turn on break mode
176 or SC01CTR_BKE,d2 176 or SC01CTR_BKE,d2
177 movhu d2,(SCxCTR,e2) 177 movhu d2,(SCxCTR,e2)
178 mov +(GxICR_LEVEL_1|GxICR_DETECT),d2 178 mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
179 movhu d2,(e3) # disable transmit interrupts on this 179 movhu d2,(e3) # disable transmit interrupts on this
180 # channel 180 # channel
181 movhu (e3),d2 # flush 181 movhu (e3),d2 # flush
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index db509dd80565..996384dba45d 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -44,6 +44,11 @@ static const char serial_revdate[] = "2007-11-06";
44#include <unit/timex.h> 44#include <unit/timex.h>
45#include "mn10300-serial.h" 45#include "mn10300-serial.h"
46 46
47#ifdef CONFIG_SMP
48#undef GxICR
49#define GxICR(X) CROSS_GxICR(X, 0)
50#endif /* CONFIG_SMP */
51
47#define kenter(FMT, ...) \ 52#define kenter(FMT, ...) \
48 printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__) 53 printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__)
49#define _enter(FMT, ...) \ 54#define _enter(FMT, ...) \
@@ -57,6 +62,11 @@ static const char serial_revdate[] = "2007-11-06";
57#define _proto(FMT, ...) \ 62#define _proto(FMT, ...) \
58 no_printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__) 63 no_printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__)
59 64
65#ifndef CODMSB
66/* c_cflag bit meaning */
67#define CODMSB 004000000000 /* change Transfer bit-order */
68#endif
69
60#define NR_UARTS 3 70#define NR_UARTS 3
61 71
62#ifdef CONFIG_MN10300_TTYSM_CONSOLE 72#ifdef CONFIG_MN10300_TTYSM_CONSOLE
@@ -152,26 +162,35 @@ struct mn10300_serial_port mn10300_serial_port_sif0 = {
152 .name = "ttySM0", 162 .name = "ttySM0",
153 ._iobase = &SC0CTR, 163 ._iobase = &SC0CTR,
154 ._control = &SC0CTR, 164 ._control = &SC0CTR,
155 ._status = (volatile u8 *) &SC0STR, 165 ._status = (volatile u8 *)&SC0STR,
156 ._intr = &SC0ICR, 166 ._intr = &SC0ICR,
157 ._rxb = &SC0RXB, 167 ._rxb = &SC0RXB,
158 ._txb = &SC0TXB, 168 ._txb = &SC0TXB,
159 .rx_name = "ttySM0:Rx", 169 .rx_name = "ttySM0:Rx",
160 .tx_name = "ttySM0:Tx", 170 .tx_name = "ttySM0:Tx",
161#ifdef CONFIG_MN10300_TTYSM0_TIMER8 171#if defined(CONFIG_MN10300_TTYSM0_TIMER8)
162 .tm_name = "ttySM0:Timer8", 172 .tm_name = "ttySM0:Timer8",
163 ._tmxmd = &TM8MD, 173 ._tmxmd = &TM8MD,
164 ._tmxbr = &TM8BR, 174 ._tmxbr = &TM8BR,
165 ._tmicr = &TM8ICR, 175 ._tmicr = &TM8ICR,
166 .tm_irq = TM8IRQ, 176 .tm_irq = TM8IRQ,
167 .div_timer = MNSCx_DIV_TIMER_16BIT, 177 .div_timer = MNSCx_DIV_TIMER_16BIT,
168#else /* CONFIG_MN10300_TTYSM0_TIMER2 */ 178#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)
179 .tm_name = "ttySM0:Timer0",
180 ._tmxmd = &TM0MD,
181 ._tmxbr = (volatile u16 *)&TM0BR,
182 ._tmicr = &TM0ICR,
183 .tm_irq = TM0IRQ,
184 .div_timer = MNSCx_DIV_TIMER_8BIT,
185#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)
169 .tm_name = "ttySM0:Timer2", 186 .tm_name = "ttySM0:Timer2",
170 ._tmxmd = &TM2MD, 187 ._tmxmd = &TM2MD,
171 ._tmxbr = (volatile u16 *) &TM2BR, 188 ._tmxbr = (volatile u16 *)&TM2BR,
172 ._tmicr = &TM2ICR, 189 ._tmicr = &TM2ICR,
173 .tm_irq = TM2IRQ, 190 .tm_irq = TM2IRQ,
174 .div_timer = MNSCx_DIV_TIMER_8BIT, 191 .div_timer = MNSCx_DIV_TIMER_8BIT,
192#else
193#error "Unknown config for ttySM0"
175#endif 194#endif
176 .rx_irq = SC0RXIRQ, 195 .rx_irq = SC0RXIRQ,
177 .tx_irq = SC0TXIRQ, 196 .tx_irq = SC0TXIRQ,
@@ -205,26 +224,35 @@ struct mn10300_serial_port mn10300_serial_port_sif1 = {
205 .name = "ttySM1", 224 .name = "ttySM1",
206 ._iobase = &SC1CTR, 225 ._iobase = &SC1CTR,
207 ._control = &SC1CTR, 226 ._control = &SC1CTR,
208 ._status = (volatile u8 *) &SC1STR, 227 ._status = (volatile u8 *)&SC1STR,
209 ._intr = &SC1ICR, 228 ._intr = &SC1ICR,
210 ._rxb = &SC1RXB, 229 ._rxb = &SC1RXB,
211 ._txb = &SC1TXB, 230 ._txb = &SC1TXB,
212 .rx_name = "ttySM1:Rx", 231 .rx_name = "ttySM1:Rx",
213 .tx_name = "ttySM1:Tx", 232 .tx_name = "ttySM1:Tx",
214#ifdef CONFIG_MN10300_TTYSM1_TIMER9 233#if defined(CONFIG_MN10300_TTYSM1_TIMER9)
215 .tm_name = "ttySM1:Timer9", 234 .tm_name = "ttySM1:Timer9",
216 ._tmxmd = &TM9MD, 235 ._tmxmd = &TM9MD,
217 ._tmxbr = &TM9BR, 236 ._tmxbr = &TM9BR,
218 ._tmicr = &TM9ICR, 237 ._tmicr = &TM9ICR,
219 .tm_irq = TM9IRQ, 238 .tm_irq = TM9IRQ,
220 .div_timer = MNSCx_DIV_TIMER_16BIT, 239 .div_timer = MNSCx_DIV_TIMER_16BIT,
221#else /* CONFIG_MN10300_TTYSM1_TIMER3 */ 240#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
222 .tm_name = "ttySM1:Timer3", 241 .tm_name = "ttySM1:Timer3",
223 ._tmxmd = &TM3MD, 242 ._tmxmd = &TM3MD,
224 ._tmxbr = (volatile u16 *) &TM3BR, 243 ._tmxbr = (volatile u16 *)&TM3BR,
225 ._tmicr = &TM3ICR, 244 ._tmicr = &TM3ICR,
226 .tm_irq = TM3IRQ, 245 .tm_irq = TM3IRQ,
227 .div_timer = MNSCx_DIV_TIMER_8BIT, 246 .div_timer = MNSCx_DIV_TIMER_8BIT,
247#elif defined(CONFIG_MN10300_TTYSM1_TIMER12)
248 .tm_name = "ttySM1/Timer12",
249 ._tmxmd = &TM12MD,
250 ._tmxbr = &TM12BR,
251 ._tmicr = &TM12ICR,
252 .tm_irq = TM12IRQ,
253 .div_timer = MNSCx_DIV_TIMER_16BIT,
254#else
255#error "Unknown config for ttySM1"
228#endif 256#endif
229 .rx_irq = SC1RXIRQ, 257 .rx_irq = SC1RXIRQ,
230 .tx_irq = SC1TXIRQ, 258 .tx_irq = SC1TXIRQ,
@@ -260,20 +288,45 @@ struct mn10300_serial_port mn10300_serial_port_sif2 = {
260 .uart.lock = 288 .uart.lock =
261 __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock), 289 __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock),
262 .name = "ttySM2", 290 .name = "ttySM2",
263 .rx_name = "ttySM2:Rx",
264 .tx_name = "ttySM2:Tx",
265 .tm_name = "ttySM2:Timer10",
266 ._iobase = &SC2CTR, 291 ._iobase = &SC2CTR,
267 ._control = &SC2CTR, 292 ._control = &SC2CTR,
268 ._status = &SC2STR, 293 ._status = (volatile u8 *)&SC2STR,
269 ._intr = &SC2ICR, 294 ._intr = &SC2ICR,
270 ._rxb = &SC2RXB, 295 ._rxb = &SC2RXB,
271 ._txb = &SC2TXB, 296 ._txb = &SC2TXB,
297 .rx_name = "ttySM2:Rx",
298 .tx_name = "ttySM2:Tx",
299#if defined(CONFIG_MN10300_TTYSM2_TIMER10)
300 .tm_name = "ttySM2/Timer10",
272 ._tmxmd = &TM10MD, 301 ._tmxmd = &TM10MD,
273 ._tmxbr = &TM10BR, 302 ._tmxbr = &TM10BR,
274 ._tmicr = &TM10ICR, 303 ._tmicr = &TM10ICR,
275 .tm_irq = TM10IRQ, 304 .tm_irq = TM10IRQ,
276 .div_timer = MNSCx_DIV_TIMER_16BIT, 305 .div_timer = MNSCx_DIV_TIMER_16BIT,
306#elif defined(CONFIG_MN10300_TTYSM2_TIMER9)
307 .tm_name = "ttySM2/Timer9",
308 ._tmxmd = &TM9MD,
309 ._tmxbr = &TM9BR,
310 ._tmicr = &TM9ICR,
311 .tm_irq = TM9IRQ,
312 .div_timer = MNSCx_DIV_TIMER_16BIT,
313#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)
314 .tm_name = "ttySM2/Timer1",
315 ._tmxmd = &TM1MD,
316 ._tmxbr = (volatile u16 *)&TM1BR,
317 ._tmicr = &TM1ICR,
318 .tm_irq = TM1IRQ,
319 .div_timer = MNSCx_DIV_TIMER_8BIT,
320#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)
321 .tm_name = "ttySM2/Timer3",
322 ._tmxmd = &TM3MD,
323 ._tmxbr = (volatile u16 *)&TM3BR,
324 ._tmicr = &TM3ICR,
325 .tm_irq = TM3IRQ,
326 .div_timer = MNSCx_DIV_TIMER_8BIT,
327#else
328#error "Unknown config for ttySM2"
329#endif
277 .rx_irq = SC2RXIRQ, 330 .rx_irq = SC2RXIRQ,
278 .tx_irq = SC2TXIRQ, 331 .tx_irq = SC2TXIRQ,
279 .rx_icr = &GxICR(SC2RXIRQ), 332 .rx_icr = &GxICR(SC2RXIRQ),
@@ -322,9 +375,13 @@ struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = {
322 */ 375 */
323static void mn10300_serial_mask_ack(unsigned int irq) 376static void mn10300_serial_mask_ack(unsigned int irq)
324{ 377{
378 unsigned long flags;
325 u16 tmp; 379 u16 tmp;
380
381 flags = arch_local_cli_save();
326 GxICR(irq) = GxICR_LEVEL_6; 382 GxICR(irq) = GxICR_LEVEL_6;
327 tmp = GxICR(irq); /* flush write buffer */ 383 tmp = GxICR(irq); /* flush write buffer */
384 arch_local_irq_restore(flags);
328} 385}
329 386
330static void mn10300_serial_nop(unsigned int irq) 387static void mn10300_serial_nop(unsigned int irq)
@@ -348,23 +405,36 @@ struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS];
348 405
349static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port) 406static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port)
350{ 407{
408 unsigned long flags;
351 u16 x; 409 u16 x;
352 *port->tx_icr = GxICR_LEVEL_1 | GxICR_DETECT; 410
411 flags = arch_local_cli_save();
412 *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
353 x = *port->tx_icr; 413 x = *port->tx_icr;
414 arch_local_irq_restore(flags);
354} 415}
355 416
356static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port) 417static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port)
357{ 418{
419 unsigned long flags;
358 u16 x; 420 u16 x;
359 *port->tx_icr = GxICR_LEVEL_1 | GxICR_ENABLE; 421
422 flags = arch_local_cli_save();
423 *port->tx_icr =
424 NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE;
360 x = *port->tx_icr; 425 x = *port->tx_icr;
426 arch_local_irq_restore(flags);
361} 427}
362 428
363static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port) 429static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port)
364{ 430{
431 unsigned long flags;
365 u16 x; 432 u16 x;
366 *port->rx_icr = GxICR_LEVEL_1 | GxICR_DETECT; 433
434 flags = arch_local_cli_save();
435 *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
367 x = *port->rx_icr; 436 x = *port->rx_icr;
437 arch_local_irq_restore(flags);
368} 438}
369 439
370/* 440/*
@@ -650,7 +720,7 @@ static unsigned int mn10300_serial_tx_empty(struct uart_port *_port)
650static void mn10300_serial_set_mctrl(struct uart_port *_port, 720static void mn10300_serial_set_mctrl(struct uart_port *_port,
651 unsigned int mctrl) 721 unsigned int mctrl)
652{ 722{
653 struct mn10300_serial_port *port = 723 struct mn10300_serial_port *port __attribute__ ((unused)) =
654 container_of(_port, struct mn10300_serial_port, uart); 724 container_of(_port, struct mn10300_serial_port, uart);
655 725
656 _enter("%s,%x", port->name, mctrl); 726 _enter("%s,%x", port->name, mctrl);
@@ -706,6 +776,7 @@ static void mn10300_serial_start_tx(struct uart_port *_port)
706 UART_XMIT_SIZE)); 776 UART_XMIT_SIZE));
707 777
708 /* kick the virtual DMA controller */ 778 /* kick the virtual DMA controller */
779 arch_local_cli();
709 x = *port->tx_icr; 780 x = *port->tx_icr;
710 x |= GxICR_ENABLE; 781 x |= GxICR_ENABLE;
711 782
@@ -716,10 +787,14 @@ static void mn10300_serial_start_tx(struct uart_port *_port)
716 787
717 _debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx", 788 _debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx",
718 *port->_control, *port->_intr, *port->_status, 789 *port->_control, *port->_intr, *port->_status,
719 *port->_tmxmd, *port->_tmxbr, *port->tx_icr); 790 *port->_tmxmd,
791 (port->div_timer == MNSCx_DIV_TIMER_8BIT) ?
792 *(volatile u8 *)port->_tmxbr : *port->_tmxbr,
793 *port->tx_icr);
720 794
721 *port->tx_icr = x; 795 *port->tx_icr = x;
722 x = *port->tx_icr; 796 x = *port->tx_icr;
797 arch_local_sti();
723} 798}
724 799
725/* 800/*
@@ -842,8 +917,10 @@ static int mn10300_serial_startup(struct uart_port *_port)
842 pint->port = port; 917 pint->port = port;
843 pint->vdma = mn10300_serial_vdma_tx_handler; 918 pint->vdma = mn10300_serial_vdma_tx_handler;
844 919
845 set_intr_level(port->rx_irq, GxICR_LEVEL_1); 920 set_intr_level(port->rx_irq,
846 set_intr_level(port->tx_irq, GxICR_LEVEL_1); 921 NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
922 set_intr_level(port->tx_irq,
923 NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
847 set_irq_chip(port->tm_irq, &mn10300_serial_pic); 924 set_irq_chip(port->tm_irq, &mn10300_serial_pic);
848 925
849 if (request_irq(port->rx_irq, mn10300_serial_interrupt, 926 if (request_irq(port->rx_irq, mn10300_serial_interrupt,
@@ -876,6 +953,7 @@ error:
876 */ 953 */
877static void mn10300_serial_shutdown(struct uart_port *_port) 954static void mn10300_serial_shutdown(struct uart_port *_port)
878{ 955{
956 u16 x;
879 struct mn10300_serial_port *port = 957 struct mn10300_serial_port *port =
880 container_of(_port, struct mn10300_serial_port, uart); 958 container_of(_port, struct mn10300_serial_port, uart);
881 959
@@ -897,8 +975,12 @@ static void mn10300_serial_shutdown(struct uart_port *_port)
897 free_irq(port->rx_irq, port); 975 free_irq(port->rx_irq, port);
898 free_irq(port->tx_irq, port); 976 free_irq(port->tx_irq, port);
899 977
900 *port->rx_icr = GxICR_LEVEL_1; 978 arch_local_cli();
901 *port->tx_icr = GxICR_LEVEL_1; 979 *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
980 x = *port->rx_icr;
981 *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
982 x = *port->tx_icr;
983 arch_local_sti();
902} 984}
903 985
904/* 986/*
@@ -947,11 +1029,66 @@ static void mn10300_serial_change_speed(struct mn10300_serial_port *port,
947 /* Determine divisor based on baud rate */ 1029 /* Determine divisor based on baud rate */
948 battempt = 0; 1030 battempt = 0;
949 1031
950 if (div_timer == MNSCx_DIV_TIMER_16BIT) 1032 switch (port->uart.line) {
951 scxctr |= SC0CTR_CK_TM8UFLOW_8; /* ( == SC1CTR_CK_TM9UFLOW_8 1033#ifdef CONFIG_MN10300_TTYSM0
952 * == SC2CTR_CK_TM10UFLOW) */ 1034 case 0: /* ttySM0 */
953 else if (div_timer == MNSCx_DIV_TIMER_8BIT) 1035#if defined(CONFIG_MN10300_TTYSM0_TIMER8)
1036 scxctr |= SC0CTR_CK_TM8UFLOW_8;
1037#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)
1038 scxctr |= SC0CTR_CK_TM0UFLOW_8;
1039#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)
954 scxctr |= SC0CTR_CK_TM2UFLOW_8; 1040 scxctr |= SC0CTR_CK_TM2UFLOW_8;
1041#else
1042#error "Unknown config for ttySM0"
1043#endif
1044 break;
1045#endif /* CONFIG_MN10300_TTYSM0 */
1046
1047#ifdef CONFIG_MN10300_TTYSM1
1048 case 1: /* ttySM1 */
1049#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
1050#if defined(CONFIG_MN10300_TTYSM1_TIMER9)
1051 scxctr |= SC1CTR_CK_TM9UFLOW_8;
1052#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
1053 scxctr |= SC1CTR_CK_TM3UFLOW_8;
1054#else
1055#error "Unknown config for ttySM1"
1056#endif
1057#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
1058#if defined(CONFIG_MN10300_TTYSM1_TIMER12)
1059 scxctr |= SC1CTR_CK_TM12UFLOW_8;
1060#else
1061#error "Unknown config for ttySM1"
1062#endif
1063#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
1064 break;
1065#endif /* CONFIG_MN10300_TTYSM1 */
1066
1067#ifdef CONFIG_MN10300_TTYSM2
1068 case 2: /* ttySM2 */
1069#if defined(CONFIG_AM33_2)
1070#if defined(CONFIG_MN10300_TTYSM2_TIMER10)
1071 scxctr |= SC2CTR_CK_TM10UFLOW;
1072#else
1073#error "Unknown config for ttySM2"
1074#endif
1075#else /* CONFIG_AM33_2 */
1076#if defined(CONFIG_MN10300_TTYSM2_TIMER9)
1077 scxctr |= SC2CTR_CK_TM9UFLOW_8;
1078#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)
1079 scxctr |= SC2CTR_CK_TM1UFLOW_8;
1080#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)
1081 scxctr |= SC2CTR_CK_TM3UFLOW_8;
1082#else
1083#error "Unknown config for ttySM2"
1084#endif
1085#endif /* CONFIG_AM33_2 */
1086 break;
1087#endif /* CONFIG_MN10300_TTYSM2 */
1088
1089 default:
1090 break;
1091 }
955 1092
956try_alternative: 1093try_alternative:
957 baud = uart_get_baud_rate(&port->uart, new, old, 0, 1094 baud = uart_get_baud_rate(&port->uart, new, old, 0,
@@ -1195,6 +1332,12 @@ static void mn10300_serial_set_termios(struct uart_port *_port,
1195 ctr &= ~SC2CTR_TWE; 1332 ctr &= ~SC2CTR_TWE;
1196 *port->_control = ctr; 1333 *port->_control = ctr;
1197 } 1334 }
1335
1336 /* change Transfer bit-order (LSB/MSB) */
1337 if (new->c_cflag & CODMSB)
1338 *port->_control |= SC01CTR_OD_MSBFIRST; /* MSB MODE */
1339 else
1340 *port->_control &= ~SC01CTR_OD_MSBFIRST; /* LSB MODE */
1198} 1341}
1199 1342
1200/* 1343/*
@@ -1302,11 +1445,16 @@ static int __init mn10300_serial_init(void)
1302 printk(KERN_INFO "%s version %s (%s)\n", 1445 printk(KERN_INFO "%s version %s (%s)\n",
1303 serial_name, serial_version, serial_revdate); 1446 serial_name, serial_version, serial_revdate);
1304 1447
1305#ifdef CONFIG_MN10300_TTYSM2 1448#if defined(CONFIG_MN10300_TTYSM2) && defined(CONFIG_AM33_2)
1306 SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */ 1449 {
1450 int tmp;
1451 SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */
1452 tmp = SC2TIM;
1453 }
1307#endif 1454#endif
1308 1455
1309 set_intr_stub(EXCEP_IRQ_LEVEL1, mn10300_serial_vdma_interrupt); 1456 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL),
1457 mn10300_serial_vdma_interrupt);
1310 1458
1311 ret = uart_register_driver(&mn10300_serial_driver); 1459 ret = uart_register_driver(&mn10300_serial_driver);
1312 if (!ret) { 1460 if (!ret) {
@@ -1366,9 +1514,11 @@ static void mn10300_serial_console_write(struct console *co,
1366 port = mn10300_serial_ports[co->index]; 1514 port = mn10300_serial_ports[co->index];
1367 1515
1368 /* firstly hijack the serial port from the "virtual DMA" controller */ 1516 /* firstly hijack the serial port from the "virtual DMA" controller */
1517 arch_local_cli();
1369 txicr = *port->tx_icr; 1518 txicr = *port->tx_icr;
1370 *port->tx_icr = GxICR_LEVEL_1; 1519 *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
1371 tmp = *port->tx_icr; 1520 tmp = *port->tx_icr;
1521 arch_local_sti();
1372 1522
1373 /* the transmitter may be disabled */ 1523 /* the transmitter may be disabled */
1374 scxctr = *port->_control; 1524 scxctr = *port->_control;
@@ -1422,8 +1572,10 @@ static void mn10300_serial_console_write(struct console *co,
1422 if (!(scxctr & SC01CTR_TXE)) 1572 if (!(scxctr & SC01CTR_TXE))
1423 *port->_control = scxctr; 1573 *port->_control = scxctr;
1424 1574
1575 arch_local_cli();
1425 *port->tx_icr = txicr; 1576 *port->tx_icr = txicr;
1426 tmp = *port->tx_icr; 1577 tmp = *port->tx_icr;
1578 arch_local_sti();
1427} 1579}
1428 1580
1429/* 1581/*
diff --git a/arch/mn10300/kernel/mn10300-watchdog-low.S b/arch/mn10300/kernel/mn10300-watchdog-low.S
index 996244745cca..f2f5c9cfaabd 100644
--- a/arch/mn10300/kernel/mn10300-watchdog-low.S
+++ b/arch/mn10300/kernel/mn10300-watchdog-low.S
@@ -16,6 +16,7 @@
16#include <asm/intctl-regs.h> 16#include <asm/intctl-regs.h>
17#include <asm/timer-regs.h> 17#include <asm/timer-regs.h>
18#include <asm/frame.inc> 18#include <asm/frame.inc>
19#include <linux/threads.h>
19 20
20 .text 21 .text
21 22
@@ -53,7 +54,13 @@ watchdog_handler:
53 .type touch_nmi_watchdog,@function 54 .type touch_nmi_watchdog,@function
54touch_nmi_watchdog: 55touch_nmi_watchdog:
55 clr d0 56 clr d0
56 mov d0,(watchdog_alert_counter) 57 clr d1
58 mov watchdog_alert_counter, a0
59 setlb
60 mov d0, (a0+)
61 inc d1
62 cmp NR_CPUS, d1
63 lne
57 ret [],0 64 ret [],0
58 65
59 .size touch_nmi_watchdog,.-touch_nmi_watchdog 66 .size touch_nmi_watchdog,.-touch_nmi_watchdog
diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c
index f362d9d138f1..965dd61656c3 100644
--- a/arch/mn10300/kernel/mn10300-watchdog.c
+++ b/arch/mn10300/kernel/mn10300-watchdog.c
@@ -30,7 +30,7 @@
30static DEFINE_SPINLOCK(watchdog_print_lock); 30static DEFINE_SPINLOCK(watchdog_print_lock);
31static unsigned int watchdog; 31static unsigned int watchdog;
32static unsigned int watchdog_hz = 1; 32static unsigned int watchdog_hz = 1;
33unsigned int watchdog_alert_counter; 33unsigned int watchdog_alert_counter[NR_CPUS];
34 34
35EXPORT_SYMBOL(touch_nmi_watchdog); 35EXPORT_SYMBOL(touch_nmi_watchdog);
36 36
@@ -39,9 +39,6 @@ EXPORT_SYMBOL(touch_nmi_watchdog);
39 * is to check its timer makes IRQ counts. If they are not 39 * is to check its timer makes IRQ counts. If they are not
40 * changing then that CPU has some problem. 40 * changing then that CPU has some problem.
41 * 41 *
42 * as these watchdog NMI IRQs are generated on every CPU, we only
43 * have to check the current processor.
44 *
45 * since NMIs dont listen to _any_ locks, we have to be extremely 42 * since NMIs dont listen to _any_ locks, we have to be extremely
46 * careful not to rely on unsafe variables. The printk might lock 43 * careful not to rely on unsafe variables. The printk might lock
47 * up though, so we have to break up any console locks first ... 44 * up though, so we have to break up any console locks first ...
@@ -69,8 +66,8 @@ int __init check_watchdog(void)
69 66
70 printk(KERN_INFO "OK.\n"); 67 printk(KERN_INFO "OK.\n");
71 68
72 /* now that we know it works we can reduce NMI frequency to 69 /* now that we know it works we can reduce NMI frequency to something
73 * something more reasonable; makes a difference in some configs 70 * more reasonable; makes a difference in some configs
74 */ 71 */
75 watchdog_hz = 1; 72 watchdog_hz = 1;
76 73
@@ -121,15 +118,22 @@ void __init watchdog_go(void)
121 } 118 }
122} 119}
123 120
121#ifdef CONFIG_SMP
122static void watchdog_dump_register(void *dummy)
123{
124 printk(KERN_ERR "--- Register Dump (CPU%d) ---\n", CPUID);
125 show_registers(__frame);
126}
127#endif
128
124asmlinkage 129asmlinkage
125void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep) 130void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep)
126{ 131{
127
128 /* 132 /*
129 * Since current-> is always on the stack, and we always switch 133 * Since current-> is always on the stack, and we always switch
130 * the stack NMI-atomically, it's safe to use smp_processor_id(). 134 * the stack NMI-atomically, it's safe to use smp_processor_id().
131 */ 135 */
132 int sum, cpu = smp_processor_id(); 136 int sum, cpu;
133 int irq = NMIIRQ; 137 int irq = NMIIRQ;
134 u8 wdt, tmp; 138 u8 wdt, tmp;
135 139
@@ -138,43 +142,61 @@ void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep)
138 tmp = WDCTR; 142 tmp = WDCTR;
139 NMICR = NMICR_WDIF; 143 NMICR = NMICR_WDIF;
140 144
141 nmi_count(cpu)++; 145 nmi_count(smp_processor_id())++;
142 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); 146 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
143 sum = irq_stat[cpu].__irq_count; 147
144 148 for_each_online_cpu(cpu) {
145 if (last_irq_sums[cpu] == sum) { 149
146 /* 150 sum = irq_stat[cpu].__irq_count;
147 * Ayiee, looks like this CPU is stuck ... 151
148 * wait a few IRQs (5 seconds) before doing the oops ... 152 if ((last_irq_sums[cpu] == sum)
149 */ 153#if defined(CONFIG_GDBSTUB) && defined(CONFIG_SMP)
150 watchdog_alert_counter++; 154 && !(CHK_GDBSTUB_BUSY()
151 if (watchdog_alert_counter == 5 * watchdog_hz) { 155 || atomic_read(&cpu_doing_single_step))
152 spin_lock(&watchdog_print_lock); 156#endif
157 ) {
153 /* 158 /*
154 * We are in trouble anyway, lets at least try 159 * Ayiee, looks like this CPU is stuck ...
155 * to get a message out. 160 * wait a few IRQs (5 seconds) before doing the oops ...
156 */ 161 */
157 bust_spinlocks(1); 162 watchdog_alert_counter[cpu]++;
158 printk(KERN_ERR 163 if (watchdog_alert_counter[cpu] == 5 * watchdog_hz) {
159 "NMI Watchdog detected LOCKUP on CPU%d," 164 spin_lock(&watchdog_print_lock);
160 " pc %08lx, registers:\n", 165 /*
161 cpu, regs->pc); 166 * We are in trouble anyway, lets at least try
162 show_registers(regs); 167 * to get a message out.
163 printk("console shuts up ...\n"); 168 */
164 console_silent(); 169 bust_spinlocks(1);
165 spin_unlock(&watchdog_print_lock); 170 printk(KERN_ERR
166 bust_spinlocks(0); 171 "NMI Watchdog detected LOCKUP on CPU%d,"
172 " pc %08lx, registers:\n",
173 cpu, regs->pc);
174#ifdef CONFIG_SMP
175 printk(KERN_ERR
176 "--- Register Dump (CPU%d) ---\n",
177 CPUID);
178#endif
179 show_registers(regs);
180#ifdef CONFIG_SMP
181 smp_nmi_call_function(watchdog_dump_register,
182 NULL, 1);
183#endif
184 printk(KERN_NOTICE "console shuts up ...\n");
185 console_silent();
186 spin_unlock(&watchdog_print_lock);
187 bust_spinlocks(0);
167#ifdef CONFIG_GDBSTUB 188#ifdef CONFIG_GDBSTUB
168 if (gdbstub_busy) 189 if (CHK_GDBSTUB_BUSY_AND_ACTIVE())
169 gdbstub_exception(regs, excep); 190 gdbstub_exception(regs, excep);
170 else 191 else
171 gdbstub_intercept(regs, excep); 192 gdbstub_intercept(regs, excep);
172#endif 193#endif
173 do_exit(SIGSEGV); 194 do_exit(SIGSEGV);
195 }
196 } else {
197 last_irq_sums[cpu] = sum;
198 watchdog_alert_counter[cpu] = 0;
174 } 199 }
175 } else {
176 last_irq_sums[cpu] = sum;
177 watchdog_alert_counter = 0;
178 } 200 }
179 201
180 WDCTR = wdt | WDCTR_WDRST; 202 WDCTR = wdt | WDCTR_WDRST;
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index 243e33cd874b..b2e85ed73a54 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -57,6 +57,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
57void (*pm_power_off)(void); 57void (*pm_power_off)(void);
58EXPORT_SYMBOL(pm_power_off); 58EXPORT_SYMBOL(pm_power_off);
59 59
60#if !defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
60/* 61/*
61 * we use this if we don't have any better idle routine 62 * we use this if we don't have any better idle routine
62 */ 63 */
@@ -69,6 +70,35 @@ static void default_idle(void)
69 local_irq_enable(); 70 local_irq_enable();
70} 71}
71 72
73#else /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */
74/*
75 * On SMP it's slightly faster (but much more power-consuming!)
76 * to poll the ->work.need_resched flag instead of waiting for the
77 * cross-CPU IPI to arrive. Use this option with caution.
78 */
79static inline void poll_idle(void)
80{
81 int oldval;
82
83 local_irq_enable();
84
85 /*
86 * Deal with another CPU just having chosen a thread to
87 * run here:
88 */
89 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
90
91 if (!oldval) {
92 set_thread_flag(TIF_POLLING_NRFLAG);
93 while (!need_resched())
94 cpu_relax();
95 clear_thread_flag(TIF_POLLING_NRFLAG);
96 } else {
97 set_need_resched();
98 }
99}
100#endif /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */
101
72/* 102/*
73 * the idle thread 103 * the idle thread
74 * - there's no useful work to be done, so just try to conserve power and have 104 * - there's no useful work to be done, so just try to conserve power and have
@@ -77,8 +107,6 @@ static void default_idle(void)
77 */ 107 */
78void cpu_idle(void) 108void cpu_idle(void)
79{ 109{
80 int cpu = smp_processor_id();
81
82 /* endless idle loop with no priority at all */ 110 /* endless idle loop with no priority at all */
83 for (;;) { 111 for (;;) {
84 while (!need_resched()) { 112 while (!need_resched()) {
@@ -86,8 +114,13 @@ void cpu_idle(void)
86 114
87 smp_rmb(); 115 smp_rmb();
88 idle = pm_idle; 116 idle = pm_idle;
89 if (!idle) 117 if (!idle) {
118#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
119 idle = poll_idle;
120#else /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
90 idle = default_idle; 121 idle = default_idle;
122#endif /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
123 }
91 idle(); 124 idle();
92 } 125 }
93 126
@@ -233,7 +266,7 @@ int copy_thread(unsigned long clone_flags,
233 } 266 }
234 267
235 /* set up things up so the scheduler can start the new task */ 268 /* set up things up so the scheduler can start the new task */
236 p->thread.__frame = c_kregs; 269 p->thread.frame = c_kregs;
237 p->thread.a3 = (unsigned long) c_kregs; 270 p->thread.a3 = (unsigned long) c_kregs;
238 p->thread.sp = c_ksp; 271 p->thread.sp = c_ksp;
239 p->thread.pc = (unsigned long) ret_from_fork; 272 p->thread.pc = (unsigned long) ret_from_fork;
diff --git a/arch/mn10300/kernel/profile.c b/arch/mn10300/kernel/profile.c
index 20d7d0306b16..4f342f75d00c 100644
--- a/arch/mn10300/kernel/profile.c
+++ b/arch/mn10300/kernel/profile.c
@@ -41,7 +41,7 @@ static __init int profile_init(void)
41 tmp = TM11ICR; 41 tmp = TM11ICR;
42 42
43 printk(KERN_INFO "Profiling initiated on timer 11, priority 0, %uHz\n", 43 printk(KERN_INFO "Profiling initiated on timer 11, priority 0, %uHz\n",
44 mn10300_ioclk / 8 / (TM11BR + 1)); 44 MN10300_IOCLK / 8 / (TM11BR + 1));
45 printk(KERN_INFO "Profile histogram stored %p-%p\n", 45 printk(KERN_INFO "Profile histogram stored %p-%p\n",
46 prof_buffer, (u8 *)(prof_buffer + prof_len) - 1); 46 prof_buffer, (u8 *)(prof_buffer + prof_len) - 1);
47 47
diff --git a/arch/mn10300/kernel/rtc.c b/arch/mn10300/kernel/rtc.c
index 4eef0e7224f6..e9e20f9a4dd3 100644
--- a/arch/mn10300/kernel/rtc.c
+++ b/arch/mn10300/kernel/rtc.c
@@ -20,18 +20,22 @@
20DEFINE_SPINLOCK(rtc_lock); 20DEFINE_SPINLOCK(rtc_lock);
21EXPORT_SYMBOL(rtc_lock); 21EXPORT_SYMBOL(rtc_lock);
22 22
23/* time for RTC to update itself in ioclks */ 23/*
24static unsigned long mn10300_rtc_update_period; 24 * Read the current RTC time
25 25 */
26void read_persistent_clock(struct timespec *ts) 26void read_persistent_clock(struct timespec *ts)
27{ 27{
28 struct rtc_time tm; 28 struct rtc_time tm;
29 29
30 get_rtc_time(&tm); 30 get_rtc_time(&tm);
31 31
32 ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday,
33 tm.tm_hour, tm.tm_min, tm.tm_sec);
34 ts->tv_nsec = 0; 32 ts->tv_nsec = 0;
33 ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday,
34 tm.tm_hour, tm.tm_min, tm.tm_sec);
35
36 /* if rtc is way off in the past, set something reasonable */
37 if (ts->tv_sec < 0)
38 ts->tv_sec = mktime(2009, 1, 1, 12, 0, 0);
35} 39}
36 40
37/* 41/*
@@ -115,39 +119,14 @@ int update_persistent_clock(struct timespec now)
115 */ 119 */
116void __init calibrate_clock(void) 120void __init calibrate_clock(void)
117{ 121{
118 unsigned long count0, counth, count1;
119 unsigned char status; 122 unsigned char status;
120 123
121 /* make sure the RTC is running and is set to operate in 24hr mode */ 124 /* make sure the RTC is running and is set to operate in 24hr mode */
122 status = RTSRC; 125 status = RTSRC;
123 RTCRB |= RTCRB_SET; 126 RTCRB |= RTCRB_SET;
124 RTCRB |= RTCRB_TM_24HR; 127 RTCRB |= RTCRB_TM_24HR;
128 RTCRB &= ~RTCRB_DM_BINARY;
125 RTCRA |= RTCRA_DVR; 129 RTCRA |= RTCRA_DVR;
126 RTCRA &= ~RTCRA_DVR; 130 RTCRA &= ~RTCRA_DVR;
127 RTCRB &= ~RTCRB_SET; 131 RTCRB &= ~RTCRB_SET;
128
129 /* work out the clock speed by counting clock cycles between ends of
130 * the RTC update cycle - track the RTC through one complete update
131 * cycle (1 second)
132 */
133 startup_timestamp_counter();
134
135 while (!(RTCRA & RTCRA_UIP)) {}
136 while ((RTCRA & RTCRA_UIP)) {}
137
138 count0 = TMTSCBC;
139
140 while (!(RTCRA & RTCRA_UIP)) {}
141
142 counth = TMTSCBC;
143
144 while ((RTCRA & RTCRA_UIP)) {}
145
146 count1 = TMTSCBC;
147
148 shutdown_timestamp_counter();
149
150 MN10300_TSCCLK = count0 - count1; /* the timers count down */
151 mn10300_rtc_update_period = counth - count1;
152 MN10300_TSC_PER_HZ = MN10300_TSCCLK / HZ;
153} 132}
diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c
index d464affcba0e..12514570ed5d 100644
--- a/arch/mn10300/kernel/setup.c
+++ b/arch/mn10300/kernel/setup.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/seq_file.h> 24#include <linux/seq_file.h>
25#include <linux/cpu.h>
25#include <asm/processor.h> 26#include <asm/processor.h>
26#include <linux/console.h> 27#include <linux/console.h>
27#include <asm/uaccess.h> 28#include <asm/uaccess.h>
@@ -30,7 +31,6 @@
30#include <asm/io.h> 31#include <asm/io.h>
31#include <asm/smp.h> 32#include <asm/smp.h>
32#include <proc/proc.h> 33#include <proc/proc.h>
33#include <asm/busctl-regs.h>
34#include <asm/fpu.h> 34#include <asm/fpu.h>
35#include <asm/sections.h> 35#include <asm/sections.h>
36 36
@@ -64,11 +64,13 @@ unsigned long memory_size;
64struct thread_info *__current_ti = &init_thread_union.thread_info; 64struct thread_info *__current_ti = &init_thread_union.thread_info;
65struct task_struct *__current = &init_task; 65struct task_struct *__current = &init_task;
66 66
67#define mn10300_known_cpus 3 67#define mn10300_known_cpus 5
68static const char *const mn10300_cputypes[] = { 68static const char *const mn10300_cputypes[] = {
69 "am33v1", 69 "am33-1",
70 "am33v2", 70 "am33-2",
71 "am34v1", 71 "am34-1",
72 "am33-3",
73 "am34-2",
72 "unknown" 74 "unknown"
73}; 75};
74 76
@@ -123,6 +125,7 @@ void __init setup_arch(char **cmdline_p)
123 125
124 cpu_init(); 126 cpu_init();
125 unit_setup(); 127 unit_setup();
128 smp_init_cpus();
126 parse_mem_cmdline(cmdline_p); 129 parse_mem_cmdline(cmdline_p);
127 130
128 init_mm.start_code = (unsigned long)&_text; 131 init_mm.start_code = (unsigned long)&_text;
@@ -179,7 +182,6 @@ void __init setup_arch(char **cmdline_p)
179void __init cpu_init(void) 182void __init cpu_init(void)
180{ 183{
181 unsigned long cpurev = CPUREV, type; 184 unsigned long cpurev = CPUREV, type;
182 unsigned long base, size;
183 185
184 type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S; 186 type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S;
185 if (type > mn10300_known_cpus) 187 if (type > mn10300_known_cpus)
@@ -189,47 +191,46 @@ void __init cpu_init(void)
189 mn10300_cputypes[type], 191 mn10300_cputypes[type],
190 (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S); 192 (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S);
191 193
192 /* determine the memory size and base from the memory controller regs */ 194 get_mem_info(&phys_memory_base, &memory_size);
193 memory_size = 0; 195 phys_memory_end = phys_memory_base + memory_size;
194
195 base = SDBASE(0);
196 if (base & SDBASE_CE) {
197 size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
198 size = ~size + 1;
199 base &= SDBASE_CBA;
200 196
201 printk(KERN_INFO "SDRAM[0]: %luMb @%08lx\n", size >> 20, base); 197 fpu_init_state();
202 memory_size += size; 198}
203 phys_memory_base = base;
204 }
205 199
206 base = SDBASE(1); 200static struct cpu cpu_devices[NR_CPUS];
207 if (base & SDBASE_CE) {
208 size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
209 size = ~size + 1;
210 base &= SDBASE_CBA;
211 201
212 printk(KERN_INFO "SDRAM[1]: %luMb @%08lx\n", size >> 20, base); 202static int __init topology_init(void)
213 memory_size += size; 203{
214 if (phys_memory_base == 0) 204 int i;
215 phys_memory_base = base;
216 }
217 205
218 phys_memory_end = phys_memory_base + memory_size; 206 for_each_present_cpu(i)
207 register_cpu(&cpu_devices[i], i);
219 208
220#ifdef CONFIG_FPU 209 return 0;
221 fpu_init_state();
222#endif
223} 210}
224 211
212subsys_initcall(topology_init);
213
225/* 214/*
226 * Get CPU information for use by the procfs. 215 * Get CPU information for use by the procfs.
227 */ 216 */
228static int show_cpuinfo(struct seq_file *m, void *v) 217static int show_cpuinfo(struct seq_file *m, void *v)
229{ 218{
219#ifdef CONFIG_SMP
220 struct mn10300_cpuinfo *c = v;
221 unsigned long cpu_id = c - cpu_data;
222 unsigned long cpurev = c->type, type, icachesz, dcachesz;
223#else /* CONFIG_SMP */
224 unsigned long cpu_id = 0;
230 unsigned long cpurev = CPUREV, type, icachesz, dcachesz; 225 unsigned long cpurev = CPUREV, type, icachesz, dcachesz;
226#endif /* CONFIG_SMP */
231 227
232 type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S; 228#ifdef CONFIG_SMP
229 if (!cpu_online(cpu_id))
230 return 0;
231#endif
232
233 type = (cpurev & CPUREV_TYPE) >> CPUREV_TYPE_S;
233 if (type > mn10300_known_cpus) 234 if (type > mn10300_known_cpus)
234 type = mn10300_known_cpus; 235 type = mn10300_known_cpus;
235 236
@@ -244,13 +245,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
244 1024; 245 1024;
245 246
246 seq_printf(m, 247 seq_printf(m,
247 "processor : 0\n" 248 "processor : %ld\n"
248 "vendor_id : Matsushita\n" 249 "vendor_id : Matsushita\n"
249 "cpu core : %s\n" 250 "cpu core : %s\n"
250 "cpu rev : %lu\n" 251 "cpu rev : %lu\n"
251 "model name : " PROCESSOR_MODEL_NAME "\n" 252 "model name : " PROCESSOR_MODEL_NAME "\n"
252 "icache size: %lu\n" 253 "icache size: %lu\n"
253 "dcache size: %lu\n", 254 "dcache size: %lu\n",
255 cpu_id,
254 mn10300_cputypes[type], 256 mn10300_cputypes[type],
255 (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S, 257 (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S,
256 icachesz, 258 icachesz,
@@ -262,8 +264,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
262 "bogomips : %lu.%02lu\n\n", 264 "bogomips : %lu.%02lu\n\n",
263 MN10300_IOCLK / 1000000, 265 MN10300_IOCLK / 1000000,
264 (MN10300_IOCLK / 10000) % 100, 266 (MN10300_IOCLK / 10000) % 100,
267#ifdef CONFIG_SMP
268 c->loops_per_jiffy / (500000 / HZ),
269 (c->loops_per_jiffy / (5000 / HZ)) % 100
270#else /* CONFIG_SMP */
265 loops_per_jiffy / (500000 / HZ), 271 loops_per_jiffy / (500000 / HZ),
266 (loops_per_jiffy / (5000 / HZ)) % 100 272 (loops_per_jiffy / (5000 / HZ)) % 100
273#endif /* CONFIG_SMP */
267 ); 274 );
268 275
269 return 0; 276 return 0;
diff --git a/arch/mn10300/kernel/smp-low.S b/arch/mn10300/kernel/smp-low.S
new file mode 100644
index 000000000000..72938cefc05e
--- /dev/null
+++ b/arch/mn10300/kernel/smp-low.S
@@ -0,0 +1,97 @@
1/* SMP IPI low-level handler
2 *
3 * Copyright (C) 2006-2007 Matsushita Electric Industrial Co., Ltd.
4 * All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <linux/sys.h>
14#include <linux/linkage.h>
15#include <asm/smp.h>
16#include <asm/system.h>
17#include <asm/thread_info.h>
18#include <asm/cpu-regs.h>
19#include <proc/smp-regs.h>
20#include <asm/asm-offsets.h>
21#include <asm/frame.inc>
22
23 .am33_2
24
25###############################################################################
26#
27# IPI interrupt handler
28#
29###############################################################################
30 .globl mn10300_low_ipi_handler
31mn10300_low_ipi_handler:
32 add -4,sp
33 mov d0,(sp)
34 movhu (IAGR),d0
35 and IAGR_GN,d0
36 lsr 0x2,d0
37#ifdef CONFIG_MN10300_CACHE_ENABLED
38 cmp FLUSH_CACHE_IPI,d0
39 beq mn10300_flush_cache_ipi
40#endif
41 cmp SMP_BOOT_IRQ,d0
42 beq mn10300_smp_boot_ipi
43 /* OTHERS */
44 mov (sp),d0
45 add 4,sp
46#ifdef CONFIG_GDBSTUB
47 jmp gdbstub_io_rx_handler
48#else
49 jmp end
50#endif
51
52###############################################################################
53#
54# Cache flush IPI interrupt handler
55#
56###############################################################################
57#ifdef CONFIG_MN10300_CACHE_ENABLED
58mn10300_flush_cache_ipi:
59 mov (sp),d0
60 add 4,sp
61
62 /* FLUSH_CACHE_IPI */
63 add -4,sp
64 SAVE_ALL
65 mov GxICR_DETECT,d2
66 movbu d2,(GxICR(FLUSH_CACHE_IPI)) # ACK the interrupt
67 movhu (GxICR(FLUSH_CACHE_IPI)),d2
68 call smp_cache_interrupt[],0
69 RESTORE_ALL
70 jmp end
71#endif
72
73###############################################################################
74#
75# SMP boot CPU IPI interrupt handler
76#
77###############################################################################
78mn10300_smp_boot_ipi:
79 /* clear interrupt */
80 movhu (GxICR(SMP_BOOT_IRQ)),d0
81 and ~GxICR_REQUEST,d0
82 movhu d0,(GxICR(SMP_BOOT_IRQ))
83 mov (sp),d0
84 add 4,sp
85
86 # get stack
87 mov (CPUID),a0
88 add -1,a0
89 add a0,a0
90 add a0,a0
91 mov (start_stack,a0),a0
92 mov a0,sp
93 jmp initialize_secondary
94
95
96# Jump here after RTI to suppress the icache lookahead
97end:
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
new file mode 100644
index 000000000000..b80234c28e0d
--- /dev/null
+++ b/arch/mn10300/kernel/smp.c
@@ -0,0 +1,1141 @@
1/* SMP support routines.
2 *
3 * Copyright (C) 2006-2008 Panasonic Corporation
4 * All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/interrupt.h>
17#include <linux/spinlock.h>
18#include <linux/init.h>
19#include <linux/jiffies.h>
20#include <linux/cpumask.h>
21#include <linux/err.h>
22#include <linux/kernel.h>
23#include <linux/delay.h>
24#include <linux/sched.h>
25#include <linux/profile.h>
26#include <linux/smp.h>
27#include <asm/tlbflush.h>
28#include <asm/system.h>
29#include <asm/bitops.h>
30#include <asm/processor.h>
31#include <asm/bug.h>
32#include <asm/exceptions.h>
33#include <asm/hardirq.h>
34#include <asm/fpu.h>
35#include <asm/mmu_context.h>
36#include <asm/thread_info.h>
37#include <asm/cpu-regs.h>
38#include <asm/intctl-regs.h>
39#include "internal.h"
40
41#ifdef CONFIG_HOTPLUG_CPU
42#include <linux/cpu.h>
43#include <asm/cacheflush.h>
44
45static unsigned long sleep_mode[NR_CPUS];
46
47static void run_sleep_cpu(unsigned int cpu);
48static void run_wakeup_cpu(unsigned int cpu);
49#endif /* CONFIG_HOTPLUG_CPU */
50
51/*
52 * Debug Message function
53 */
54
55#undef DEBUG_SMP
56#ifdef DEBUG_SMP
57#define Dprintk(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
58#else
59#define Dprintk(fmt, ...) no_printk(KERN_DEBUG fmt, ##__VA_ARGS__)
60#endif
61
62/* timeout value in msec for smp_nmi_call_function. zero is no timeout. */
63#define CALL_FUNCTION_NMI_IPI_TIMEOUT 0
64
65/*
66 * Structure and data for smp_nmi_call_function().
67 */
68struct nmi_call_data_struct {
69 smp_call_func_t func;
70 void *info;
71 cpumask_t started;
72 cpumask_t finished;
73 int wait;
74 char size_alignment[0]
75 __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
76} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
77
78static DEFINE_SPINLOCK(smp_nmi_call_lock);
79static struct nmi_call_data_struct *nmi_call_data;
80
81/*
82 * Data structures and variables
83 */
84static cpumask_t cpu_callin_map; /* Bitmask of callin CPUs */
85static cpumask_t cpu_callout_map; /* Bitmask of callout CPUs */
86cpumask_t cpu_boot_map; /* Bitmask of boot APs */
87unsigned long start_stack[NR_CPUS - 1];
88
89/*
90 * Per CPU parameters
91 */
92struct mn10300_cpuinfo cpu_data[NR_CPUS] __cacheline_aligned;
93
94static int cpucount; /* The count of boot CPUs */
95static cpumask_t smp_commenced_mask;
96cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
97
98/*
99 * Function Prototypes
100 */
101static int do_boot_cpu(int);
102static void smp_show_cpu_info(int cpu_id);
103static void smp_callin(void);
104static void smp_online(void);
105static void smp_store_cpu_info(int);
106static void smp_cpu_init(void);
107static void smp_tune_scheduling(void);
108static void send_IPI_mask(const cpumask_t *cpumask, int irq);
109static void init_ipi(void);
110
111/*
112 * IPI Initialization interrupt definitions
113 */
114static void mn10300_ipi_disable(unsigned int irq);
115static void mn10300_ipi_enable(unsigned int irq);
116static void mn10300_ipi_ack(unsigned int irq);
117static void mn10300_ipi_nop(unsigned int irq);
118
119static struct irq_chip mn10300_ipi_type = {
120 .name = "cpu_ipi",
121 .disable = mn10300_ipi_disable,
122 .enable = mn10300_ipi_enable,
123 .ack = mn10300_ipi_ack,
124 .eoi = mn10300_ipi_nop
125};
126
127static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id);
128static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id);
129static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id);
130
131static struct irqaction reschedule_ipi = {
132 .handler = smp_reschedule_interrupt,
133 .name = "smp reschedule IPI"
134};
135static struct irqaction call_function_ipi = {
136 .handler = smp_call_function_interrupt,
137 .name = "smp call function IPI"
138};
139static struct irqaction local_timer_ipi = {
140 .handler = smp_ipi_timer_interrupt,
141 .flags = IRQF_DISABLED,
142 .name = "smp local timer IPI"
143};
144
145/**
146 * init_ipi - Initialise the IPI mechanism
147 */
148static void init_ipi(void)
149{
150 unsigned long flags;
151 u16 tmp16;
152
153 /* set up the reschedule IPI */
154 set_irq_chip_and_handler(RESCHEDULE_IPI,
155 &mn10300_ipi_type, handle_percpu_irq);
156 setup_irq(RESCHEDULE_IPI, &reschedule_ipi);
157 set_intr_level(RESCHEDULE_IPI, RESCHEDULE_GxICR_LV);
158 mn10300_ipi_enable(RESCHEDULE_IPI);
159
160 /* set up the call function IPI */
161 set_irq_chip_and_handler(CALL_FUNC_SINGLE_IPI,
162 &mn10300_ipi_type, handle_percpu_irq);
163 setup_irq(CALL_FUNC_SINGLE_IPI, &call_function_ipi);
164 set_intr_level(CALL_FUNC_SINGLE_IPI, CALL_FUNCTION_GxICR_LV);
165 mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI);
166
167 /* set up the local timer IPI */
168 set_irq_chip_and_handler(LOCAL_TIMER_IPI,
169 &mn10300_ipi_type, handle_percpu_irq);
170 setup_irq(LOCAL_TIMER_IPI, &local_timer_ipi);
171 set_intr_level(LOCAL_TIMER_IPI, LOCAL_TIMER_GxICR_LV);
172 mn10300_ipi_enable(LOCAL_TIMER_IPI);
173
174#ifdef CONFIG_MN10300_CACHE_ENABLED
175 /* set up the cache flush IPI */
176 flags = arch_local_cli_save();
177 __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(FLUSH_CACHE_GxICR_LV),
178 mn10300_low_ipi_handler);
179 GxICR(FLUSH_CACHE_IPI) = FLUSH_CACHE_GxICR_LV | GxICR_DETECT;
180 mn10300_ipi_enable(FLUSH_CACHE_IPI);
181 arch_local_irq_restore(flags);
182#endif
183
184 /* set up the NMI call function IPI */
185 flags = arch_local_cli_save();
186 GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
187 tmp16 = GxICR(CALL_FUNCTION_NMI_IPI);
188 arch_local_irq_restore(flags);
189
190 /* set up the SMP boot IPI */
191 flags = arch_local_cli_save();
192 __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(SMP_BOOT_GxICR_LV),
193 mn10300_low_ipi_handler);
194 arch_local_irq_restore(flags);
195}
196
197/**
198 * mn10300_ipi_shutdown - Shut down handling of an IPI
199 * @irq: The IPI to be shut down.
200 */
201static void mn10300_ipi_shutdown(unsigned int irq)
202{
203 unsigned long flags;
204 u16 tmp;
205
206 flags = arch_local_cli_save();
207
208 tmp = GxICR(irq);
209 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
210 tmp = GxICR(irq);
211
212 arch_local_irq_restore(flags);
213}
214
215/**
216 * mn10300_ipi_enable - Enable an IPI
217 * @irq: The IPI to be enabled.
218 */
219static void mn10300_ipi_enable(unsigned int irq)
220{
221 unsigned long flags;
222 u16 tmp;
223
224 flags = arch_local_cli_save();
225
226 tmp = GxICR(irq);
227 GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
228 tmp = GxICR(irq);
229
230 arch_local_irq_restore(flags);
231}
232
233/**
234 * mn10300_ipi_disable - Disable an IPI
235 * @irq: The IPI to be disabled.
236 */
237static void mn10300_ipi_disable(unsigned int irq)
238{
239 unsigned long flags;
240 u16 tmp;
241
242 flags = arch_local_cli_save();
243
244 tmp = GxICR(irq);
245 GxICR(irq) = tmp & GxICR_LEVEL;
246 tmp = GxICR(irq);
247
248 arch_local_irq_restore(flags);
249}
250
251/**
252 * mn10300_ipi_ack - Acknowledge an IPI interrupt in the PIC
253 * @irq: The IPI to be acknowledged.
254 *
255 * Clear the interrupt detection flag for the IPI on the appropriate interrupt
256 * channel in the PIC.
257 */
258static void mn10300_ipi_ack(unsigned int irq)
259{
260 unsigned long flags;
261 u16 tmp;
262
263 flags = arch_local_cli_save();
264 GxICR_u8(irq) = GxICR_DETECT;
265 tmp = GxICR(irq);
266 arch_local_irq_restore(flags);
267}
268
269/**
270 * mn10300_ipi_nop - Dummy IPI action
271 * @irq: The IPI to be acted upon.
272 */
273static void mn10300_ipi_nop(unsigned int irq)
274{
275}
276
277/**
278 * send_IPI_mask - Send IPIs to all CPUs in list
279 * @cpumask: The list of CPUs to target.
280 * @irq: The IPI request to be sent.
281 *
282 * Send the specified IPI to all the CPUs in the list, not waiting for them to
283 * finish before returning. The caller is responsible for synchronisation if
284 * that is needed.
285 */
286static void send_IPI_mask(const cpumask_t *cpumask, int irq)
287{
288 int i;
289 u16 tmp;
290
291 for (i = 0; i < NR_CPUS; i++) {
292 if (cpu_isset(i, *cpumask)) {
293 /* send IPI */
294 tmp = CROSS_GxICR(irq, i);
295 CROSS_GxICR(irq, i) =
296 tmp | GxICR_REQUEST | GxICR_DETECT;
297 tmp = CROSS_GxICR(irq, i); /* flush write buffer */
298 }
299 }
300}
301
302/**
303 * send_IPI_self - Send an IPI to this CPU.
304 * @irq: The IPI request to be sent.
305 *
306 * Send the specified IPI to the current CPU.
307 */
308void send_IPI_self(int irq)
309{
310 send_IPI_mask(cpumask_of(smp_processor_id()), irq);
311}
312
313/**
314 * send_IPI_allbutself - Send IPIs to all the other CPUs.
315 * @irq: The IPI request to be sent.
316 *
317 * Send the specified IPI to all CPUs in the system barring the current one,
318 * not waiting for them to finish before returning. The caller is responsible
319 * for synchronisation if that is needed.
320 */
321void send_IPI_allbutself(int irq)
322{
323 cpumask_t cpumask;
324
325 cpumask = cpu_online_map;
326 cpu_clear(smp_processor_id(), cpumask);
327 send_IPI_mask(&cpumask, irq);
328}
329
330void arch_send_call_function_ipi_mask(const struct cpumask *mask)
331{
332 BUG();
333 /*send_IPI_mask(mask, CALL_FUNCTION_IPI);*/
334}
335
336void arch_send_call_function_single_ipi(int cpu)
337{
338 send_IPI_mask(cpumask_of(cpu), CALL_FUNC_SINGLE_IPI);
339}
340
341/**
342 * smp_send_reschedule - Send reschedule IPI to a CPU
343 * @cpu: The CPU to target.
344 */
345void smp_send_reschedule(int cpu)
346{
347 send_IPI_mask(cpumask_of(cpu), RESCHEDULE_IPI);
348}
349
350/**
351 * smp_nmi_call_function - Send a call function NMI IPI to all CPUs
352 * @func: The function to ask to be run.
353 * @info: The context data to pass to that function.
354 * @wait: If true, wait (atomically) until function is run on all CPUs.
355 *
356 * Send a non-maskable request to all CPUs in the system, requesting them to
357 * run the specified function with the given context data, and, potentially, to
358 * wait for completion of that function on all CPUs.
359 *
360 * Returns 0 if successful, -ETIMEDOUT if we were asked to wait, but hit the
361 * timeout.
362 */
363int smp_nmi_call_function(smp_call_func_t func, void *info, int wait)
364{
365 struct nmi_call_data_struct data;
366 unsigned long flags;
367 unsigned int cnt;
368 int cpus, ret = 0;
369
370 cpus = num_online_cpus() - 1;
371 if (cpus < 1)
372 return 0;
373
374 data.func = func;
375 data.info = info;
376 data.started = cpu_online_map;
377 cpu_clear(smp_processor_id(), data.started);
378 data.wait = wait;
379 if (wait)
380 data.finished = data.started;
381
382 spin_lock_irqsave(&smp_nmi_call_lock, flags);
383 nmi_call_data = &data;
384 smp_mb();
385
386 /* Send a message to all other CPUs and wait for them to respond */
387 send_IPI_allbutself(CALL_FUNCTION_NMI_IPI);
388
389 /* Wait for response */
390 if (CALL_FUNCTION_NMI_IPI_TIMEOUT > 0) {
391 for (cnt = 0;
392 cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
393 !cpus_empty(data.started);
394 cnt++)
395 mdelay(1);
396
397 if (wait && cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT) {
398 for (cnt = 0;
399 cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
400 !cpus_empty(data.finished);
401 cnt++)
402 mdelay(1);
403 }
404
405 if (cnt >= CALL_FUNCTION_NMI_IPI_TIMEOUT)
406 ret = -ETIMEDOUT;
407
408 } else {
409 /* If timeout value is zero, wait until cpumask has been
410 * cleared */
411 while (!cpus_empty(data.started))
412 barrier();
413 if (wait)
414 while (!cpus_empty(data.finished))
415 barrier();
416 }
417
418 spin_unlock_irqrestore(&smp_nmi_call_lock, flags);
419 return ret;
420}
421
422/**
423 * stop_this_cpu - Callback to stop a CPU.
424 * @unused: Callback context (ignored).
425 */
426void stop_this_cpu(void *unused)
427{
428 static volatile int stopflag;
429 unsigned long flags;
430
431#ifdef CONFIG_GDBSTUB
432 /* In case of single stepping smp_send_stop by other CPU,
433 * clear procindebug to avoid deadlock.
434 */
435 atomic_set(&procindebug[smp_processor_id()], 0);
436#endif /* CONFIG_GDBSTUB */
437
438 flags = arch_local_cli_save();
439 cpu_clear(smp_processor_id(), cpu_online_map);
440
441 while (!stopflag)
442 cpu_relax();
443
444 cpu_set(smp_processor_id(), cpu_online_map);
445 arch_local_irq_restore(flags);
446}
447
448/**
449 * smp_send_stop - Send a stop request to all CPUs.
450 */
451void smp_send_stop(void)
452{
453 smp_nmi_call_function(stop_this_cpu, NULL, 0);
454}
455
456/**
457 * smp_reschedule_interrupt - Reschedule IPI handler
458 * @irq: The interrupt number.
459 * @dev_id: The device ID.
460 *
461 * We need do nothing here, since the scheduling will be effected on our way
462 * back through entry.S.
463 *
464 * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
465 */
466static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id)
467{
468 /* do nothing */
469 return IRQ_HANDLED;
470}
471
472/**
473 * smp_call_function_interrupt - Call function IPI handler
474 * @irq: The interrupt number.
475 * @dev_id: The device ID.
476 *
477 * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
478 */
479static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id)
480{
481 /* generic_smp_call_function_interrupt(); */
482 generic_smp_call_function_single_interrupt();
483 return IRQ_HANDLED;
484}
485
486/**
487 * smp_nmi_call_function_interrupt - Non-maskable call function IPI handler
488 */
489void smp_nmi_call_function_interrupt(void)
490{
491 smp_call_func_t func = nmi_call_data->func;
492 void *info = nmi_call_data->info;
493 int wait = nmi_call_data->wait;
494
495 /* Notify the initiating CPU that I've grabbed the data and am about to
496 * execute the function
497 */
498 smp_mb();
499 cpu_clear(smp_processor_id(), nmi_call_data->started);
500 (*func)(info);
501
502 if (wait) {
503 smp_mb();
504 cpu_clear(smp_processor_id(), nmi_call_data->finished);
505 }
506}
507
508/**
509 * smp_ipi_timer_interrupt - Local timer IPI handler
510 * @irq: The interrupt number.
511 * @dev_id: The device ID.
512 *
513 * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
514 */
515static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id)
516{
517 return local_timer_interrupt();
518}
519
520void __init smp_init_cpus(void)
521{
522 int i;
523 for (i = 0; i < NR_CPUS; i++) {
524 set_cpu_possible(i, true);
525 set_cpu_present(i, true);
526 }
527}
528
529/**
530 * smp_cpu_init - Initialise AP in start_secondary.
531 *
532 * For this Application Processor, set up init_mm, initialise FPU and set
533 * interrupt level 0-6 setting.
534 */
535static void __init smp_cpu_init(void)
536{
537 unsigned long flags;
538 int cpu_id = smp_processor_id();
539 u16 tmp16;
540
541 if (test_and_set_bit(cpu_id, &cpu_initialized)) {
542 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu_id);
543 for (;;)
544 local_irq_enable();
545 }
546 printk(KERN_INFO "Initializing CPU#%d\n", cpu_id);
547
548 atomic_inc(&init_mm.mm_count);
549 current->active_mm = &init_mm;
550 BUG_ON(current->mm);
551
552 enter_lazy_tlb(&init_mm, current);
553
554 /* Force FPU initialization */
555 clear_using_fpu(current);
556
557 GxICR(CALL_FUNC_SINGLE_IPI) = CALL_FUNCTION_GxICR_LV | GxICR_DETECT;
558 mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI);
559
560 GxICR(LOCAL_TIMER_IPI) = LOCAL_TIMER_GxICR_LV | GxICR_DETECT;
561 mn10300_ipi_enable(LOCAL_TIMER_IPI);
562
563 GxICR(RESCHEDULE_IPI) = RESCHEDULE_GxICR_LV | GxICR_DETECT;
564 mn10300_ipi_enable(RESCHEDULE_IPI);
565
566#ifdef CONFIG_MN10300_CACHE_ENABLED
567 GxICR(FLUSH_CACHE_IPI) = FLUSH_CACHE_GxICR_LV | GxICR_DETECT;
568 mn10300_ipi_enable(FLUSH_CACHE_IPI);
569#endif
570
571 mn10300_ipi_shutdown(SMP_BOOT_IRQ);
572
573 /* Set up the non-maskable call function IPI */
574 flags = arch_local_cli_save();
575 GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
576 tmp16 = GxICR(CALL_FUNCTION_NMI_IPI);
577 arch_local_irq_restore(flags);
578}
579
580/**
581 * smp_prepare_cpu_init - Initialise CPU in startup_secondary
582 *
583 * Set interrupt level 0-6 setting and init ICR of gdbstub.
584 */
585void smp_prepare_cpu_init(void)
586{
587 int loop;
588
589 /* Set the interrupt vector registers */
590 IVAR0 = EXCEP_IRQ_LEVEL0;
591 IVAR1 = EXCEP_IRQ_LEVEL1;
592 IVAR2 = EXCEP_IRQ_LEVEL2;
593 IVAR3 = EXCEP_IRQ_LEVEL3;
594 IVAR4 = EXCEP_IRQ_LEVEL4;
595 IVAR5 = EXCEP_IRQ_LEVEL5;
596 IVAR6 = EXCEP_IRQ_LEVEL6;
597
598 /* Disable all interrupts and set to priority 6 (lowest) */
599 for (loop = 0; loop < GxICR_NUM_IRQS; loop++)
600 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
601
602#ifdef CONFIG_GDBSTUB
603 /* initialise GDB-stub */
604 do {
605 unsigned long flags;
606 u16 tmp16;
607
608 flags = arch_local_cli_save();
609 GxICR(GDB_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
610 tmp16 = GxICR(GDB_NMI_IPI);
611 arch_local_irq_restore(flags);
612 } while (0);
613#endif
614}
615
616/**
617 * start_secondary - Activate a secondary CPU (AP)
618 * @unused: Thread parameter (ignored).
619 */
620int __init start_secondary(void *unused)
621{
622 smp_cpu_init();
623
624 smp_callin();
625 while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
626 cpu_relax();
627
628 local_flush_tlb();
629 preempt_disable();
630 smp_online();
631
632 cpu_idle();
633 return 0;
634}
635
636/**
637 * smp_prepare_cpus - Boot up secondary CPUs (APs)
638 * @max_cpus: Maximum number of CPUs to boot.
639 *
640 * Call do_boot_cpu, and boot up APs.
641 */
642void __init smp_prepare_cpus(unsigned int max_cpus)
643{
644 int phy_id;
645
646 /* Setup boot CPU information */
647 smp_store_cpu_info(0);
648 smp_tune_scheduling();
649
650 init_ipi();
651
652 /* If SMP should be disabled, then finish */
653 if (max_cpus == 0) {
654 printk(KERN_INFO "SMP mode deactivated.\n");
655 goto smp_done;
656 }
657
658 /* Boot secondary CPUs (for which phy_id > 0) */
659 for (phy_id = 0; phy_id < NR_CPUS; phy_id++) {
660 /* Don't boot primary CPU */
661 if (max_cpus <= cpucount + 1)
662 continue;
663 if (phy_id != 0)
664 do_boot_cpu(phy_id);
665 set_cpu_possible(phy_id, true);
666 smp_show_cpu_info(phy_id);
667 }
668
669smp_done:
670 Dprintk("Boot done.\n");
671}
672
673/**
674 * smp_store_cpu_info - Save a CPU's information
675 * @cpu: The CPU to save for.
676 *
677 * Save boot_cpu_data and jiffy for the specified CPU.
678 */
679static void __init smp_store_cpu_info(int cpu)
680{
681 struct mn10300_cpuinfo *ci = &cpu_data[cpu];
682
683 *ci = boot_cpu_data;
684 ci->loops_per_jiffy = loops_per_jiffy;
685 ci->type = CPUREV;
686}
687
688/**
689 * smp_tune_scheduling - Set time slice value
690 *
691 * Nothing to do here.
692 */
693static void __init smp_tune_scheduling(void)
694{
695}
696
697/**
698 * do_boot_cpu: Boot up one CPU
699 * @phy_id: Physical ID of CPU to boot.
700 *
701 * Send an IPI to a secondary CPU to boot it. Returns 0 on success, 1
702 * otherwise.
703 */
704static int __init do_boot_cpu(int phy_id)
705{
706 struct task_struct *idle;
707 unsigned long send_status, callin_status;
708 int timeout, cpu_id;
709
710 send_status = GxICR_REQUEST;
711 callin_status = 0;
712 timeout = 0;
713 cpu_id = phy_id;
714
715 cpucount++;
716
717 /* Create idle thread for this CPU */
718 idle = fork_idle(cpu_id);
719 if (IS_ERR(idle))
720 panic("Failed fork for CPU#%d.", cpu_id);
721
722 idle->thread.pc = (unsigned long)start_secondary;
723
724 printk(KERN_NOTICE "Booting CPU#%d\n", cpu_id);
725 start_stack[cpu_id - 1] = idle->thread.sp;
726
727 task_thread_info(idle)->cpu = cpu_id;
728
729 /* Send boot IPI to AP */
730 send_IPI_mask(cpumask_of(phy_id), SMP_BOOT_IRQ);
731
732 Dprintk("Waiting for send to finish...\n");
733
734 /* Wait for AP's IPI receive in 100[ms] */
735 do {
736 udelay(1000);
737 send_status =
738 CROSS_GxICR(SMP_BOOT_IRQ, phy_id) & GxICR_REQUEST;
739 } while (send_status == GxICR_REQUEST && timeout++ < 100);
740
741 Dprintk("Waiting for cpu_callin_map.\n");
742
743 if (send_status == 0) {
744 /* Allow AP to start initializing */
745 cpu_set(cpu_id, cpu_callout_map);
746
747 /* Wait for setting cpu_callin_map */
748 timeout = 0;
749 do {
750 udelay(1000);
751 callin_status = cpu_isset(cpu_id, cpu_callin_map);
752 } while (callin_status == 0 && timeout++ < 5000);
753
754 if (callin_status == 0)
755 Dprintk("Not responding.\n");
756 } else {
757 printk(KERN_WARNING "IPI not delivered.\n");
758 }
759
760 if (send_status == GxICR_REQUEST || callin_status == 0) {
761 cpu_clear(cpu_id, cpu_callout_map);
762 cpu_clear(cpu_id, cpu_callin_map);
763 cpu_clear(cpu_id, cpu_initialized);
764 cpucount--;
765 return 1;
766 }
767 return 0;
768}
769
770/**
771 * smp_show_cpu_info - Show SMP CPU information
772 * @cpu: The CPU of interest.
773 */
774static void __init smp_show_cpu_info(int cpu)
775{
776 struct mn10300_cpuinfo *ci = &cpu_data[cpu];
777
778 printk(KERN_INFO
779 "CPU#%d : ioclk speed: %lu.%02luMHz : bogomips : %lu.%02lu\n",
780 cpu,
781 MN10300_IOCLK / 1000000,
782 (MN10300_IOCLK / 10000) % 100,
783 ci->loops_per_jiffy / (500000 / HZ),
784 (ci->loops_per_jiffy / (5000 / HZ)) % 100);
785}
786
787/**
788 * smp_callin - Set cpu_callin_map of the current CPU ID
789 */
790static void __init smp_callin(void)
791{
792 unsigned long timeout;
793 int cpu;
794
795 cpu = smp_processor_id();
796 timeout = jiffies + (2 * HZ);
797
798 if (cpu_isset(cpu, cpu_callin_map)) {
799 printk(KERN_ERR "CPU#%d already present.\n", cpu);
800 BUG();
801 }
802 Dprintk("CPU#%d waiting for CALLOUT\n", cpu);
803
804 /* Wait for AP startup 2s total */
805 while (time_before(jiffies, timeout)) {
806 if (cpu_isset(cpu, cpu_callout_map))
807 break;
808 cpu_relax();
809 }
810
811 if (!time_before(jiffies, timeout)) {
812 printk(KERN_ERR
813 "BUG: CPU#%d started up but did not get a callout!\n",
814 cpu);
815 BUG();
816 }
817
818#ifdef CONFIG_CALIBRATE_DELAY
819 calibrate_delay(); /* Get our bogomips */
820#endif
821
822 /* Save our processor parameters */
823 smp_store_cpu_info(cpu);
824
825 /* Allow the boot processor to continue */
826 cpu_set(cpu, cpu_callin_map);
827}
828
829/**
830 * smp_online - Set cpu_online_map
831 */
832static void __init smp_online(void)
833{
834 int cpu;
835
836 cpu = smp_processor_id();
837
838 local_irq_enable();
839
840 cpu_set(cpu, cpu_online_map);
841 smp_wmb();
842}
843
844/**
845 * smp_cpus_done -
846 * @max_cpus: Maximum CPU count.
847 *
848 * Do nothing.
849 */
850void __init smp_cpus_done(unsigned int max_cpus)
851{
852}
853
854/*
855 * smp_prepare_boot_cpu - Set up stuff for the boot processor.
856 *
857 * Set up the cpu_online_map, cpu_callout_map and cpu_callin_map of the boot
858 * processor (CPU 0).
859 */
860void __devinit smp_prepare_boot_cpu(void)
861{
862 cpu_set(0, cpu_callout_map);
863 cpu_set(0, cpu_callin_map);
864 current_thread_info()->cpu = 0;
865}
866
867/*
868 * initialize_secondary - Initialise a secondary CPU (Application Processor).
869 *
870 * Set SP register and jump to thread's PC address.
871 */
872void initialize_secondary(void)
873{
874 asm volatile (
875 "mov %0,sp \n"
876 "jmp (%1) \n"
877 :
878 : "a"(current->thread.sp), "a"(current->thread.pc));
879}
880
881/**
882 * __cpu_up - Set smp_commenced_mask for the nominated CPU
883 * @cpu: The target CPU.
884 */
885int __devinit __cpu_up(unsigned int cpu)
886{
887 int timeout;
888
889#ifdef CONFIG_HOTPLUG_CPU
890 if (num_online_cpus() == 1)
891 disable_hlt();
892 if (sleep_mode[cpu])
893 run_wakeup_cpu(cpu);
894#endif /* CONFIG_HOTPLUG_CPU */
895
896 cpu_set(cpu, smp_commenced_mask);
897
898 /* Wait 5s total for a response */
899 for (timeout = 0 ; timeout < 5000 ; timeout++) {
900 if (cpu_isset(cpu, cpu_online_map))
901 break;
902 udelay(1000);
903 }
904
905 BUG_ON(!cpu_isset(cpu, cpu_online_map));
906 return 0;
907}
908
909/**
910 * setup_profiling_timer - Set up the profiling timer
911 * @multiplier - The frequency multiplier to use
912 *
913 * The frequency of the profiling timer can be changed by writing a multiplier
914 * value into /proc/profile.
915 */
916int setup_profiling_timer(unsigned int multiplier)
917{
918 return -EINVAL;
919}
920
921/*
922 * CPU hotplug routines
923 */
924#ifdef CONFIG_HOTPLUG_CPU
925
926static DEFINE_PER_CPU(struct cpu, cpu_devices);
927
928static int __init topology_init(void)
929{
930 int cpu, ret;
931
932 for_each_cpu(cpu) {
933 ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
934 if (ret)
935 printk(KERN_WARNING
936 "topology_init: register_cpu %d failed (%d)\n",
937 cpu, ret);
938 }
939 return 0;
940}
941
942subsys_initcall(topology_init);
943
944int __cpu_disable(void)
945{
946 int cpu = smp_processor_id();
947 if (cpu == 0)
948 return -EBUSY;
949
950 migrate_irqs();
951 cpu_clear(cpu, current->active_mm->cpu_vm_mask);
952 return 0;
953}
954
955void __cpu_die(unsigned int cpu)
956{
957 run_sleep_cpu(cpu);
958
959 if (num_online_cpus() == 1)
960 enable_hlt();
961}
962
963#ifdef CONFIG_MN10300_CACHE_ENABLED
964static inline void hotplug_cpu_disable_cache(void)
965{
966 int tmp;
967 asm volatile(
968 " movhu (%1),%0 \n"
969 " and %2,%0 \n"
970 " movhu %0,(%1) \n"
971 "1: movhu (%1),%0 \n"
972 " btst %3,%0 \n"
973 " bne 1b \n"
974 : "=&r"(tmp)
975 : "a"(&CHCTR),
976 "i"(~(CHCTR_ICEN | CHCTR_DCEN)),
977 "i"(CHCTR_ICBUSY | CHCTR_DCBUSY)
978 : "memory", "cc");
979}
980
981static inline void hotplug_cpu_enable_cache(void)
982{
983 int tmp;
984 asm volatile(
985 "movhu (%1),%0 \n"
986 "or %2,%0 \n"
987 "movhu %0,(%1) \n"
988 : "=&r"(tmp)
989 : "a"(&CHCTR),
990 "i"(CHCTR_ICEN | CHCTR_DCEN)
991 : "memory", "cc");
992}
993
994static inline void hotplug_cpu_invalidate_cache(void)
995{
996 int tmp;
997 asm volatile (
998 "movhu (%1),%0 \n"
999 "or %2,%0 \n"
1000 "movhu %0,(%1) \n"
1001 : "=&r"(tmp)
1002 : "a"(&CHCTR),
1003 "i"(CHCTR_ICINV | CHCTR_DCINV)
1004 : "cc");
1005}
1006
1007#else /* CONFIG_MN10300_CACHE_ENABLED */
1008#define hotplug_cpu_disable_cache() do {} while (0)
1009#define hotplug_cpu_enable_cache() do {} while (0)
1010#define hotplug_cpu_invalidate_cache() do {} while (0)
1011#endif /* CONFIG_MN10300_CACHE_ENABLED */
1012
1013/**
1014 * hotplug_cpu_nmi_call_function - Call a function on other CPUs for hotplug
1015 * @cpumask: List of target CPUs.
1016 * @func: The function to call on those CPUs.
1017 * @info: The context data for the function to be called.
1018 * @wait: Whether to wait for the calls to complete.
1019 *
1020 * Non-maskably call a function on another CPU for hotplug purposes.
1021 *
1022 * This function must be called with maskable interrupts disabled.
1023 */
1024static int hotplug_cpu_nmi_call_function(cpumask_t cpumask,
1025 smp_call_func_t func, void *info,
1026 int wait)
1027{
1028 /*
1029 * The address and the size of nmi_call_func_mask_data
1030 * need to be aligned on L1_CACHE_BYTES.
1031 */
1032 static struct nmi_call_data_struct nmi_call_func_mask_data
1033 __cacheline_aligned;
1034 unsigned long start, end;
1035
1036 start = (unsigned long)&nmi_call_func_mask_data;
1037 end = start + sizeof(struct nmi_call_data_struct);
1038
1039 nmi_call_func_mask_data.func = func;
1040 nmi_call_func_mask_data.info = info;
1041 nmi_call_func_mask_data.started = cpumask;
1042 nmi_call_func_mask_data.wait = wait;
1043 if (wait)
1044 nmi_call_func_mask_data.finished = cpumask;
1045
1046 spin_lock(&smp_nmi_call_lock);
1047 nmi_call_data = &nmi_call_func_mask_data;
1048 mn10300_local_dcache_flush_range(start, end);
1049 smp_wmb();
1050
1051 send_IPI_mask(cpumask, CALL_FUNCTION_NMI_IPI);
1052
1053 do {
1054 mn10300_local_dcache_inv_range(start, end);
1055 barrier();
1056 } while (!cpus_empty(nmi_call_func_mask_data.started));
1057
1058 if (wait) {
1059 do {
1060 mn10300_local_dcache_inv_range(start, end);
1061 barrier();
1062 } while (!cpus_empty(nmi_call_func_mask_data.finished));
1063 }
1064
1065 spin_unlock(&smp_nmi_call_lock);
1066 return 0;
1067}
1068
1069static void restart_wakeup_cpu(void)
1070{
1071 unsigned int cpu = smp_processor_id();
1072
1073 cpu_set(cpu, cpu_callin_map);
1074 local_flush_tlb();
1075 cpu_set(cpu, cpu_online_map);
1076 smp_wmb();
1077}
1078
1079static void prepare_sleep_cpu(void *unused)
1080{
1081 sleep_mode[smp_processor_id()] = 1;
1082 smp_mb();
1083 mn10300_local_dcache_flush_inv();
1084 hotplug_cpu_disable_cache();
1085 hotplug_cpu_invalidate_cache();
1086}
1087
1088/* when this function called, IE=0, NMID=0. */
1089static void sleep_cpu(void *unused)
1090{
1091 unsigned int cpu_id = smp_processor_id();
1092 /*
1093 * CALL_FUNCTION_NMI_IPI for wakeup_cpu() shall not be requested,
1094 * before this cpu goes in SLEEP mode.
1095 */
1096 do {
1097 smp_mb();
1098 __sleep_cpu();
1099 } while (sleep_mode[cpu_id]);
1100 restart_wakeup_cpu();
1101}
1102
1103static void run_sleep_cpu(unsigned int cpu)
1104{
1105 unsigned long flags;
1106 cpumask_t cpumask = cpumask_of(cpu);
1107
1108 flags = arch_local_cli_save();
1109 hotplug_cpu_nmi_call_function(cpumask, prepare_sleep_cpu, NULL, 1);
1110 hotplug_cpu_nmi_call_function(cpumask, sleep_cpu, NULL, 0);
1111 udelay(1); /* delay for the cpu to sleep. */
1112 arch_local_irq_restore(flags);
1113}
1114
1115static void wakeup_cpu(void)
1116{
1117 hotplug_cpu_invalidate_cache();
1118 hotplug_cpu_enable_cache();
1119 smp_mb();
1120 sleep_mode[smp_processor_id()] = 0;
1121}
1122
1123static void run_wakeup_cpu(unsigned int cpu)
1124{
1125 unsigned long flags;
1126
1127 flags = arch_local_cli_save();
1128#if NR_CPUS == 2
1129 mn10300_local_dcache_flush_inv();
1130#else
1131 /*
1132 * Before waking up the cpu,
1133 * all online cpus should stop and flush D-Cache for global data.
1134 */
1135#error not support NR_CPUS > 2, when CONFIG_HOTPLUG_CPU=y.
1136#endif
1137 hotplug_cpu_nmi_call_function(cpumask_of(cpu), wakeup_cpu, NULL, 1);
1138 arch_local_irq_restore(flags);
1139}
1140
1141#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S
index 630aad71b946..b08cb2e3aebd 100644
--- a/arch/mn10300/kernel/switch_to.S
+++ b/arch/mn10300/kernel/switch_to.S
@@ -15,6 +15,9 @@
15#include <linux/linkage.h> 15#include <linux/linkage.h>
16#include <asm/thread_info.h> 16#include <asm/thread_info.h>
17#include <asm/cpu-regs.h> 17#include <asm/cpu-regs.h>
18#ifdef CONFIG_SMP
19#include <proc/smp-regs.h>
20#endif /* CONFIG_SMP */
18 21
19 .text 22 .text
20 23
@@ -35,7 +38,14 @@ ENTRY(__switch_to)
35 mov d1,a1 38 mov d1,a1
36 39
37 # save prev context 40 # save prev context
41#ifdef CONFIG_SMP
42 mov (CPUID),a2
43 add a2,a2
44 add a2,a2
45 mov (___frame,a2),d0
46#else /* CONFIG_SMP */
38 mov (__frame),d0 47 mov (__frame),d0
48#endif /* CONFIG_SMP */
39 mov d0,(THREAD_FRAME,a0) 49 mov d0,(THREAD_FRAME,a0)
40 mov __switch_back,d0 50 mov __switch_back,d0
41 mov d0,(THREAD_PC,a0) 51 mov d0,(THREAD_PC,a0)
@@ -59,7 +69,14 @@ ENTRY(__switch_to)
59#endif 69#endif
60 70
61 mov (THREAD_FRAME,a1),a2 71 mov (THREAD_FRAME,a1),a2
72#ifdef CONFIG_SMP
73 mov (CPUID),a0
74 add a0,a0
75 add a0,a0
76 mov a2,(___frame,a0)
77#else /* CONFIG_SMP */
62 mov a2,(__frame) 78 mov a2,(__frame)
79#endif /* CONFIG_SMP */
63 mov (THREAD_PC,a1),a2 80 mov (THREAD_PC,a1),a2
64 mov d2,d0 # for ret_from_fork 81 mov d2,d0 # for ret_from_fork
65 mov d0,a0 # for __switch_to 82 mov d0,a0 # for __switch_to
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
index 0b5c856b4266..0cb9bdb3b6bd 100644
--- a/arch/mn10300/kernel/time.c
+++ b/arch/mn10300/kernel/time.c
@@ -22,12 +22,7 @@
22#include <asm/processor.h> 22#include <asm/processor.h>
23#include <asm/intctl-regs.h> 23#include <asm/intctl-regs.h>
24#include <asm/rtc.h> 24#include <asm/rtc.h>
25 25#include "internal.h"
26#ifdef CONFIG_MN10300_RTC
27unsigned long mn10300_ioclk; /* system I/O clock frequency */
28unsigned long mn10300_iobclk; /* system I/O clock frequency */
29unsigned long mn10300_tsc_per_HZ; /* number of ioclks per jiffy */
30#endif /* CONFIG_MN10300_RTC */
31 26
32static unsigned long mn10300_last_tsc; /* time-stamp counter at last time 27static unsigned long mn10300_last_tsc; /* time-stamp counter at last time
33 * interrupt occurred */ 28 * interrupt occurred */
@@ -95,6 +90,19 @@ static void __init mn10300_sched_clock_init(void)
95 __muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK); 90 __muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK);
96} 91}
97 92
93/**
94 * local_timer_interrupt - Local timer interrupt handler
95 *
96 * Handle local timer interrupts for this CPU. They may have been propagated
97 * to this CPU from the CPU that actually gets them by way of an IPI.
98 */
99irqreturn_t local_timer_interrupt(void)
100{
101 profile_tick(CPU_PROFILING);
102 update_process_times(user_mode(get_irq_regs()));
103 return IRQ_HANDLED;
104}
105
98/* 106/*
99 * advance the kernel's time keeping clocks (xtime and jiffies) 107 * advance the kernel's time keeping clocks (xtime and jiffies)
100 * - we use Timer 0 & 1 cascaded as a clock to nudge us the next time 108 * - we use Timer 0 & 1 cascaded as a clock to nudge us the next time
@@ -103,6 +111,7 @@ static void __init mn10300_sched_clock_init(void)
103static irqreturn_t timer_interrupt(int irq, void *dev_id) 111static irqreturn_t timer_interrupt(int irq, void *dev_id)
104{ 112{
105 unsigned tsc, elapse; 113 unsigned tsc, elapse;
114 irqreturn_t ret;
106 115
107 write_seqlock(&xtime_lock); 116 write_seqlock(&xtime_lock);
108 117
@@ -114,15 +123,16 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
114 mn10300_last_tsc -= MN10300_TSC_PER_HZ; 123 mn10300_last_tsc -= MN10300_TSC_PER_HZ;
115 124
116 /* advance the kernel's time tracking system */ 125 /* advance the kernel's time tracking system */
117 profile_tick(CPU_PROFILING);
118 do_timer(1); 126 do_timer(1);
119 } 127 }
120 128
121 write_sequnlock(&xtime_lock); 129 write_sequnlock(&xtime_lock);
122 130
123 update_process_times(user_mode(get_irq_regs())); 131 ret = local_timer_interrupt();
124 132#ifdef CONFIG_SMP
125 return IRQ_HANDLED; 133 send_IPI_allbutself(LOCAL_TIMER_IPI);
134#endif
135 return ret;
126} 136}
127 137
128/* 138/*
@@ -148,7 +158,7 @@ void __init time_init(void)
148 /* use timer 0 & 1 cascaded to tick at as close to HZ as possible */ 158 /* use timer 0 & 1 cascaded to tick at as close to HZ as possible */
149 setup_irq(TMJCIRQ, &timer_irq); 159 setup_irq(TMJCIRQ, &timer_irq);
150 160
151 set_intr_level(TMJCIRQ, TMJCICR_LEVEL); 161 set_intr_level(TMJCIRQ, NUM2GxICR_LEVEL(CONFIG_TIMER_IRQ_LEVEL));
152 162
153 startup_jiffies_counter(); 163 startup_jiffies_counter();
154 164
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index 716a221df2f9..c924a1dd3323 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -45,8 +45,13 @@
45#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" 45#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!"
46#endif 46#endif
47 47
48#ifdef CONFIG_SMP
49struct pt_regs *___frame[NR_CPUS]; /* current frame pointer */
50EXPORT_SYMBOL(___frame);
51#else /* CONFIG_SMP */
48struct pt_regs *__frame; /* current frame pointer */ 52struct pt_regs *__frame; /* current frame pointer */
49EXPORT_SYMBOL(__frame); 53EXPORT_SYMBOL(__frame);
54#endif /* CONFIG_SMP */
50 55
51int kstack_depth_to_print = 24; 56int kstack_depth_to_print = 24;
52 57
@@ -221,11 +226,14 @@ void show_registers_only(struct pt_regs *regs)
221 printk(KERN_EMERG "threadinfo=%p task=%p)\n", 226 printk(KERN_EMERG "threadinfo=%p task=%p)\n",
222 current_thread_info(), current); 227 current_thread_info(), current);
223 228
224 if ((unsigned long) current >= 0x90000000UL && 229 if ((unsigned long) current >= PAGE_OFFSET &&
225 (unsigned long) current < 0x94000000UL) 230 (unsigned long) current < (unsigned long)high_memory)
226 printk(KERN_EMERG "Process %s (pid: %d)\n", 231 printk(KERN_EMERG "Process %s (pid: %d)\n",
227 current->comm, current->pid); 232 current->comm, current->pid);
228 233
234#ifdef CONFIG_SMP
235 printk(KERN_EMERG "CPUID: %08x\n", CPUID);
236#endif
229 printk(KERN_EMERG "CPUP: %04hx\n", CPUP); 237 printk(KERN_EMERG "CPUP: %04hx\n", CPUP);
230 printk(KERN_EMERG "TBR: %08x\n", TBR); 238 printk(KERN_EMERG "TBR: %08x\n", TBR);
231 printk(KERN_EMERG "DEAR: %08x\n", DEAR); 239 printk(KERN_EMERG "DEAR: %08x\n", DEAR);
@@ -521,8 +529,12 @@ void __init set_intr_stub(enum exception_code code, void *handler)
521{ 529{
522 unsigned long addr; 530 unsigned long addr;
523 u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code); 531 u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code);
532 unsigned long flags;
524 533
525 addr = (unsigned long) handler - (unsigned long) vector; 534 addr = (unsigned long) handler - (unsigned long) vector;
535
536 flags = arch_local_cli_save();
537
526 vector[0] = 0xdc; /* JMP handler */ 538 vector[0] = 0xdc; /* JMP handler */
527 vector[1] = addr; 539 vector[1] = addr;
528 vector[2] = addr >> 8; 540 vector[2] = addr >> 8;
@@ -532,6 +544,8 @@ void __init set_intr_stub(enum exception_code code, void *handler)
532 vector[6] = 0xcb; 544 vector[6] = 0xcb;
533 vector[7] = 0xcb; 545 vector[7] = 0xcb;
534 546
547 arch_local_irq_restore(flags);
548
535#ifndef CONFIG_MN10300_CACHE_SNOOP 549#ifndef CONFIG_MN10300_CACHE_SNOOP
536 mn10300_dcache_flush_inv(); 550 mn10300_dcache_flush_inv();
537 mn10300_icache_inv(); 551 mn10300_icache_inv();
diff --git a/arch/mn10300/lib/delay.c b/arch/mn10300/lib/delay.c
index fdf6f710f94e..8e7ceb8ba33d 100644
--- a/arch/mn10300/lib/delay.c
+++ b/arch/mn10300/lib/delay.c
@@ -38,14 +38,14 @@ EXPORT_SYMBOL(__delay);
38 */ 38 */
39void __udelay(unsigned long usecs) 39void __udelay(unsigned long usecs)
40{ 40{
41 signed long ioclk, stop; 41 unsigned long start, stop, cnt;
42 42
43 /* usecs * CLK / 1E6 */ 43 /* usecs * CLK / 1E6 */
44 stop = __muldiv64u(usecs, MN10300_TSCCLK, 1000000); 44 stop = __muldiv64u(usecs, MN10300_TSCCLK, 1000000);
45 stop = TMTSCBC - stop; 45 start = TMTSCBC;
46 46
47 do { 47 do {
48 ioclk = TMTSCBC; 48 cnt = start - TMTSCBC;
49 } while (stop < ioclk); 49 } while (cnt < stop);
50} 50}
51EXPORT_SYMBOL(__udelay); 51EXPORT_SYMBOL(__udelay);
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c
index 906e4c8f9ab1..59c3da49d9d9 100644
--- a/arch/mn10300/mm/fault.c
+++ b/arch/mn10300/mm/fault.c
@@ -39,10 +39,6 @@ void bust_spinlocks(int yes)
39{ 39{
40 if (yes) { 40 if (yes) {
41 oops_in_progress = 1; 41 oops_in_progress = 1;
42#ifdef CONFIG_SMP
43 /* Many serial drivers do __global_cli() */
44 global_irq_lock = 0;
45#endif
46 } else { 42 } else {
47 int loglevel_save = console_loglevel; 43 int loglevel_save = console_loglevel;
48#ifdef CONFIG_VT 44#ifdef CONFIG_VT
@@ -334,10 +330,10 @@ no_context:
334 */ 330 */
335out_of_memory: 331out_of_memory:
336 up_read(&mm->mmap_sem); 332 up_read(&mm->mmap_sem);
337 if ((fault_code & MMUFCR_xFC_ACCESS) != MMUFCR_xFC_ACCESS_USR) 333 printk(KERN_ALERT "VM: killing process %s\n", tsk->comm);
338 goto no_context; 334 if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR)
339 pagefault_out_of_memory(); 335 do_exit(SIGKILL);
340 return; 336 goto no_context;
341 337
342do_sigbus: 338do_sigbus:
343 up_read(&mm->mmap_sem); 339 up_read(&mm->mmap_sem);
diff --git a/arch/mn10300/proc-mn103e010/include/proc/clock.h b/arch/mn10300/proc-mn103e010/include/proc/clock.h
index aa23e147d620..704a819f1f4b 100644
--- a/arch/mn10300/proc-mn103e010/include/proc/clock.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/clock.h
@@ -13,6 +13,4 @@
13 13
14#include <unit/clock.h> 14#include <unit/clock.h>
15 15
16#define MN10300_WDCLK MN10300_IOCLK
17
18#endif /* _ASM_PROC_CLOCK_H */ 16#endif /* _ASM_PROC_CLOCK_H */
diff --git a/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h b/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h
new file mode 100644
index 000000000000..f537801a44ba
--- /dev/null
+++ b/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h
@@ -0,0 +1,29 @@
1#ifndef _ASM_PROC_INTCTL_REGS_H
2#define _ASM_PROC_INTCTL_REGS_H
3
4#ifndef _ASM_INTCTL_REGS_H
5# error "please don't include this file directly"
6#endif
7
8/* intr acceptance group reg */
9#define IAGR __SYSREG(0xd4000100, u16)
10
11/* group number register */
12#define IAGR_GN 0x00fc
13
14#define __GET_XIRQ_TRIGGER(X, Z) (((Z) >> ((X) * 2)) & 3)
15
16#define __SET_XIRQ_TRIGGER(X, Y, Z) \
17({ \
18 typeof(Z) x = (Z); \
19 x &= ~(3 << ((X) * 2)); \
20 x |= ((Y) & 3) << ((X) * 2); \
21 (Z) = x; \
22})
23
24/* external pin intr spec reg */
25#define EXTMD __SYSREG(0xd4000200, u16)
26#define GET_XIRQ_TRIGGER(X) __GET_XIRQ_TRIGGER(X, EXTMD)
27#define SET_XIRQ_TRIGGER(X, Y) __SET_XIRQ_TRIGGER(X, Y, EXTMD)
28
29#endif /* _ASM_PROC_INTCTL_REGS_H */
diff --git a/arch/mn10300/proc-mn103e010/proc-init.c b/arch/mn10300/proc-mn103e010/proc-init.c
index 0cee7878bee9..27b97980dca4 100644
--- a/arch/mn10300/proc-mn103e010/proc-init.c
+++ b/arch/mn10300/proc-mn103e010/proc-init.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <asm/fpu.h> 12#include <asm/fpu.h>
13#include <asm/rtc.h> 13#include <asm/rtc.h>
14#include <asm/busctl-regs.h>
14 15
15/* 16/*
16 * initialise the on-silicon processor peripherals 17 * initialise the on-silicon processor peripherals
@@ -75,3 +76,37 @@ asmlinkage void __init processor_init(void)
75 76
76 calibrate_clock(); 77 calibrate_clock();
77} 78}
79
80/*
81 * determine the memory size and base from the memory controller regs
82 */
83void __init get_mem_info(unsigned long *mem_base, unsigned long *mem_size)
84{
85 unsigned long base, size;
86
87 *mem_base = 0;
88 *mem_size = 0;
89
90 base = SDBASE(0);
91 if (base & SDBASE_CE) {
92 size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
93 size = ~size + 1;
94 base &= SDBASE_CBA;
95
96 printk(KERN_INFO "SDRAM[0]: %luMb @%08lx\n", size >> 20, base);
97 *mem_size += size;
98 *mem_base = base;
99 }
100
101 base = SDBASE(1);
102 if (base & SDBASE_CE) {
103 size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
104 size = ~size + 1;
105 base &= SDBASE_CBA;
106
107 printk(KERN_INFO "SDRAM[1]: %luMb @%08lx\n", size >> 20, base);
108 *mem_size += size;
109 if (*mem_base == 0)
110 *mem_base = base;
111 }
112}
diff --git a/arch/mn10300/proc-mn2ws0050/Makefile b/arch/mn10300/proc-mn2ws0050/Makefile
new file mode 100644
index 000000000000..d4ca13309a85
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := proc-init.o
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
new file mode 100644
index 000000000000..cafd7b5b55b4
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
@@ -0,0 +1,48 @@
1/* Cache specification
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * Modified by Matsushita Electric Industrial Co., Ltd.
7 * Modifications:
8 * 13-Nov-2006 MEI Add L1_CACHE_SHIFT_MAX definition.
9 * 29-Jul-2008 MEI Add define for MN10300_HAS_AREAPURGE_REG.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16#ifndef _ASM_PROC_CACHE_H
17#define _ASM_PROC_CACHE_H
18
19/*
20 * L1 cache
21 */
22#define L1_CACHE_NWAYS 4 /* number of ways in caches */
23#define L1_CACHE_NENTRIES 128 /* number of entries in each way */
24#define L1_CACHE_BYTES 32 /* bytes per entry */
25#define L1_CACHE_SHIFT 5 /* shift for bytes per entry */
26#define L1_CACHE_WAYDISP 0x1000 /* distance from one way to the next */
27
28#define L1_CACHE_TAG_VALID 0x00000001 /* cache tag valid bit */
29#define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */
30#define L1_CACHE_TAG_ENTRY 0x00000fe0 /* cache tag entry address mask */
31#define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */
32
33/*
34 * specification of the interval between interrupt checking intervals whilst
35 * managing the cache with the interrupts disabled
36 */
37#define MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL 4
38
39/*
40 * The size of range at which it becomes more economical to just flush the
41 * whole cache rather than trying to flush the specified range.
42 */
43#define MN10300_DCACHE_FLUSH_BORDER \
44 +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
45#define MN10300_DCACHE_FLUSH_INV_BORDER \
46 +(L1_CACHE_NWAYS * L1_CACHE_NENTRIES * L1_CACHE_BYTES)
47
48#endif /* _ASM_PROC_CACHE_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/clock.h b/arch/mn10300/proc-mn2ws0050/include/proc/clock.h
new file mode 100644
index 000000000000..fe4c0a4a53a2
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/clock.h
@@ -0,0 +1,20 @@
1/* clock.h: proc-specific clocks
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * Modified by Matsushita Electric Industrial Co., Ltd.
7 * Modifications:
8 * 23-Feb-2007 MEI Delete define for watchdog timer.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#ifndef _ASM_PROC_CLOCK_H
16#define _ASM_PROC_CLOCK_H
17
18#include <unit/clock.h>
19
20#endif /* _ASM_PROC_CLOCK_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h
new file mode 100644
index 000000000000..4c4319e241d1
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/dmactl-regs.h
@@ -0,0 +1,103 @@
1/* MN2WS0050 on-board DMA controller registers
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 */
10
11#ifndef _ASM_PROC_DMACTL_REGS_H
12#define _ASM_PROC_DMACTL_REGS_H
13
14#include <asm/cpu-regs.h>
15
16#ifdef __KERNEL__
17
18/* DMA registers */
19#define DMxCTR(N) __SYSREG(0xd4005000+(N*0x100), u32) /* control reg */
20#define DMxCTR_BG 0x0000001f /* transfer request source */
21#define DMxCTR_BG_SOFT 0x00000000 /* - software source */
22#define DMxCTR_BG_SC0TX 0x00000002 /* - serial port 0 transmission */
23#define DMxCTR_BG_SC0RX 0x00000003 /* - serial port 0 reception */
24#define DMxCTR_BG_SC1TX 0x00000004 /* - serial port 1 transmission */
25#define DMxCTR_BG_SC1RX 0x00000005 /* - serial port 1 reception */
26#define DMxCTR_BG_SC2TX 0x00000006 /* - serial port 2 transmission */
27#define DMxCTR_BG_SC2RX 0x00000007 /* - serial port 2 reception */
28#define DMxCTR_BG_TM0UFLOW 0x00000008 /* - timer 0 underflow */
29#define DMxCTR_BG_TM1UFLOW 0x00000009 /* - timer 1 underflow */
30#define DMxCTR_BG_TM2UFLOW 0x0000000a /* - timer 2 underflow */
31#define DMxCTR_BG_TM3UFLOW 0x0000000b /* - timer 3 underflow */
32#define DMxCTR_BG_TM6ACMPCAP 0x0000000c /* - timer 6A compare/capture */
33#define DMxCTR_BG_RYBY 0x0000000d /* - NAND Flash RY/BY request source */
34#define DMxCTR_BG_RMC 0x0000000e /* - remote controller output */
35#define DMxCTR_BG_XIRQ12 0x00000011 /* - XIRQ12 pin interrupt source */
36#define DMxCTR_BG_XIRQ13 0x00000012 /* - XIRQ13 pin interrupt source */
37#define DMxCTR_BG_TCK 0x00000014 /* - tick timer underflow */
38#define DMxCTR_BG_SC4TX 0x00000019 /* - serial port4 transmission */
39#define DMxCTR_BG_SC4RX 0x0000001a /* - serial port4 reception */
40#define DMxCTR_BG_SC5TX 0x0000001b /* - serial port5 transmission */
41#define DMxCTR_BG_SC5RX 0x0000001c /* - serial port5 reception */
42#define DMxCTR_BG_SC6TX 0x0000001d /* - serial port6 transmission */
43#define DMxCTR_BG_SC6RX 0x0000001e /* - serial port6 reception */
44#define DMxCTR_BG_TMSUFLOW 0x0000001f /* - timestamp timer underflow */
45#define DMxCTR_SAM 0x00000060 /* DMA transfer src addr mode */
46#define DMxCTR_SAM_INCR 0x00000000 /* - increment */
47#define DMxCTR_SAM_DECR 0x00000020 /* - decrement */
48#define DMxCTR_SAM_FIXED 0x00000040 /* - fixed */
49#define DMxCTR_DAM 0x00000300 /* DMA transfer dest addr mode */
50#define DMxCTR_DAM_INCR 0x00000000 /* - increment */
51#define DMxCTR_DAM_DECR 0x00000100 /* - decrement */
52#define DMxCTR_DAM_FIXED 0x00000200 /* - fixed */
53#define DMxCTR_UT 0x00006000 /* DMA transfer unit */
54#define DMxCTR_UT_1 0x00000000 /* - 1 byte */
55#define DMxCTR_UT_2 0x00002000 /* - 2 byte */
56#define DMxCTR_UT_4 0x00004000 /* - 4 byte */
57#define DMxCTR_UT_16 0x00006000 /* - 16 byte */
58#define DMxCTR_RRE 0x00008000 /* DMA round robin enable */
59#define DMxCTR_TEN 0x00010000 /* DMA channel transfer enable */
60#define DMxCTR_RQM 0x00060000 /* external request input source mode */
61#define DMxCTR_RQM_FALLEDGE 0x00000000 /* - falling edge */
62#define DMxCTR_RQM_RISEEDGE 0x00020000 /* - rising edge */
63#define DMxCTR_RQM_LOLEVEL 0x00040000 /* - low level */
64#define DMxCTR_RQM_HILEVEL 0x00060000 /* - high level */
65#define DMxCTR_RQF 0x01000000 /* DMA transfer request flag */
66#define DMxCTR_PERR 0x40000000 /* DMA transfer parameter error flag */
67#define DMxCTR_XEND 0x80000000 /* DMA transfer end flag */
68
69#define DMxSRC(N) __SYSREG(0xd4005004+(N*0x100), u32) /* control reg */
70
71#define DMxDST(N) __SYSREG(0xd4005008+(N*0x100), u32) /* source addr reg */
72
73#define DMxSIZ(N) __SYSREG(0xd400500c+(N*0x100), u32) /* dest addr reg */
74#define DMxSIZ_CT 0x000fffff /* number of bytes to transfer */
75
76#define DMxCYC(N) __SYSREG(0xd4005010+(N*0x100), u32) /* intermittent size reg */
77#define DMxCYC_CYC 0x000000ff /* number of interrmittent transfers -1 */
78
79#define DM0IRQ 16 /* DMA channel 0 complete IRQ */
80#define DM1IRQ 17 /* DMA channel 1 complete IRQ */
81#define DM2IRQ 18 /* DMA channel 2 complete IRQ */
82#define DM3IRQ 19 /* DMA channel 3 complete IRQ */
83
84#define DM0ICR GxICR(DM0IRQ) /* DMA channel 0 complete intr ctrl reg */
85#define DM1ICR GxICR(DM0IR1) /* DMA channel 1 complete intr ctrl reg */
86#define DM2ICR GxICR(DM0IR2) /* DMA channel 2 complete intr ctrl reg */
87#define DM3ICR GxICR(DM0IR3) /* DMA channel 3 complete intr ctrl reg */
88
89#ifndef __ASSEMBLY__
90
91struct mn10300_dmactl_regs {
92 u32 ctr;
93 const void *src;
94 void *dst;
95 u32 siz;
96 u32 cyc;
97} __attribute__((aligned(0x100)));
98
99#endif /* __ASSEMBLY__ */
100
101#endif /* __KERNEL__ */
102
103#endif /* _ASM_PROC_DMACTL_REGS_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h
new file mode 100644
index 000000000000..a1e977273d19
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h
@@ -0,0 +1,29 @@
1#ifndef _ASM_PROC_INTCTL_REGS_H
2#define _ASM_PROC_INTCTL_REGS_H
3
4#ifndef _ASM_INTCTL_REGS_H
5# error "please don't include this file directly"
6#endif
7
8/* intr acceptance group reg */
9#define IAGR __SYSREG(0xd4000100, u16)
10
11/* group number register */
12#define IAGR_GN 0x003fc
13
14#define __GET_XIRQ_TRIGGER(X, Z) (((Z) >> ((X) * 2)) & 3)
15
16#define __SET_XIRQ_TRIGGER(X, Y, Z) \
17({ \
18 typeof(Z) x = (Z); \
19 x &= ~(3 << ((X) * 2)); \
20 x |= ((Y) & 3) << ((X) * 2); \
21 (Z) = x; \
22})
23
24/* external pin intr spec reg */
25#define EXTMD0 __SYSREG(0xd4000200, u32)
26#define GET_XIRQ_TRIGGER(X) __GET_XIRQ_TRIGGER(X, EXTMD0)
27#define SET_XIRQ_TRIGGER(X, Y) __SET_XIRQ_TRIGGER(X, Y, EXTMD0)
28
29#endif /* _ASM_PROC_INTCTL_REGS_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/irq.h b/arch/mn10300/proc-mn2ws0050/include/proc/irq.h
new file mode 100644
index 000000000000..37777a85ab6f
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/irq.h
@@ -0,0 +1,49 @@
1/* MN2WS0050 on-board interrupt controller registers
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * Modified by Matsushita Electric Industrial Co., Ltd.
7 * Modifications:
8 * 13-Nov-2006 MEI Define extended IRQ number for SMP support.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#ifndef _PROC_IRQ_H
17#define _PROC_IRQ_H
18
19#ifdef __KERNEL__
20
21#define GxICR_NUM_IRQS 163
22#ifdef CONFIG_SMP
23#define GxICR_NUM_EXT_IRQS 197
24#endif /* CONFIG_SMP */
25
26#define GxICR_NUM_XIRQS 16
27
28#define XIRQ0 34
29#define XIRQ1 35
30#define XIRQ2 36
31#define XIRQ3 37
32#define XIRQ4 38
33#define XIRQ5 39
34#define XIRQ6 40
35#define XIRQ7 41
36#define XIRQ8 42
37#define XIRQ9 43
38#define XIRQ10 44
39#define XIRQ11 45
40#define XIRQ12 46
41#define XIRQ13 47
42#define XIRQ14 48
43#define XIRQ15 49
44
45#define XIRQ2IRQ(num) (XIRQ0 + num)
46
47#endif /* __KERNEL__ */
48
49#endif /* _PROC_IRQ_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h
new file mode 100644
index 000000000000..84448f3828b3
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/nand-regs.h
@@ -0,0 +1,120 @@
1/* NAND flash interface register definitions
2 *
3 * Copyright (C) 2008-2009 Panasonic Corporation
4 * All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _PROC_NAND_REGS_H_
17#define _PROC_NAND_REGS_H_
18
19/* command register */
20#define FCOMMAND_0 __SYSREG(0xd8f00000, u8) /* fcommand[24:31] */
21#define FCOMMAND_1 __SYSREG(0xd8f00001, u8) /* fcommand[16:23] */
22#define FCOMMAND_2 __SYSREG(0xd8f00002, u8) /* fcommand[8:15] */
23#define FCOMMAND_3 __SYSREG(0xd8f00003, u8) /* fcommand[0:7] */
24
25/* for dma 16 byte trans, use FCOMMAND2 register */
26#define FCOMMAND2_0 __SYSREG(0xd8f00110, u8) /* fcommand2[24:31] */
27#define FCOMMAND2_1 __SYSREG(0xd8f00111, u8) /* fcommand2[16:23] */
28#define FCOMMAND2_2 __SYSREG(0xd8f00112, u8) /* fcommand2[8:15] */
29#define FCOMMAND2_3 __SYSREG(0xd8f00113, u8) /* fcommand2[0:7] */
30
31#define FCOMMAND_FIEN 0x80 /* nand flash I/F enable */
32#define FCOMMAND_BW_8BIT 0x00 /* 8bit bus width */
33#define FCOMMAND_BW_16BIT 0x40 /* 16bit bus width */
34#define FCOMMAND_BLOCKSZ_SMALL 0x00 /* small block */
35#define FCOMMAND_BLOCKSZ_LARGE 0x20 /* large block */
36#define FCOMMAND_DMASTART 0x10 /* dma start */
37#define FCOMMAND_RYBY 0x08 /* ready/busy flag */
38#define FCOMMAND_RYBYINTMSK 0x04 /* mask ready/busy interrupt */
39#define FCOMMAND_XFWP 0x02 /* write protect enable */
40#define FCOMMAND_XFCE 0x01 /* flash device disable */
41#define FCOMMAND_SEQKILL 0x10 /* stop seq-read */
42#define FCOMMAND_ANUM 0x07 /* address cycle */
43#define FCOMMAND_ANUM_NONE 0x00 /* address cycle none */
44#define FCOMMAND_ANUM_1CYC 0x01 /* address cycle 1cycle */
45#define FCOMMAND_ANUM_2CYC 0x02 /* address cycle 2cycle */
46#define FCOMMAND_ANUM_3CYC 0x03 /* address cycle 3cycle */
47#define FCOMMAND_ANUM_4CYC 0x04 /* address cycle 4cycle */
48#define FCOMMAND_ANUM_5CYC 0x05 /* address cycle 5cycle */
49#define FCOMMAND_FCMD_READ0 0x00 /* read1 command */
50#define FCOMMAND_FCMD_SEQIN 0x80 /* page program 1st command */
51#define FCOMMAND_FCMD_PAGEPROG 0x10 /* page program 2nd command */
52#define FCOMMAND_FCMD_RESET 0xff /* reset command */
53#define FCOMMAND_FCMD_ERASE1 0x60 /* erase 1st command */
54#define FCOMMAND_FCMD_ERASE2 0xd0 /* erase 2nd command */
55#define FCOMMAND_FCMD_STATUS 0x70 /* read status command */
56#define FCOMMAND_FCMD_READID 0x90 /* read id command */
57#define FCOMMAND_FCMD_READOOB 0x50 /* read3 command */
58/* address register */
59#define FADD __SYSREG(0xd8f00004, u32)
60/* address register 2 */
61#define FADD2 __SYSREG(0xd8f00008, u32)
62/* error judgement register */
63#define FJUDGE __SYSREG(0xd8f0000c, u32)
64#define FJUDGE_NOERR 0x0 /* no error */
65#define FJUDGE_1BITERR 0x1 /* 1bit error in data area */
66#define FJUDGE_PARITYERR 0x2 /* parity error */
67#define FJUDGE_UNCORRECTABLE 0x3 /* uncorrectable error */
68#define FJUDGE_ERRJDG_MSK 0x3 /* mask of judgement result */
69/* 1st ECC store register */
70#define FECC11 __SYSREG(0xd8f00010, u32)
71/* 2nd ECC store register */
72#define FECC12 __SYSREG(0xd8f00014, u32)
73/* 3rd ECC store register */
74#define FECC21 __SYSREG(0xd8f00018, u32)
75/* 4th ECC store register */
76#define FECC22 __SYSREG(0xd8f0001c, u32)
77/* 5th ECC store register */
78#define FECC31 __SYSREG(0xd8f00020, u32)
79/* 6th ECC store register */
80#define FECC32 __SYSREG(0xd8f00024, u32)
81/* 7th ECC store register */
82#define FECC41 __SYSREG(0xd8f00028, u32)
83/* 8th ECC store register */
84#define FECC42 __SYSREG(0xd8f0002c, u32)
85/* data register */
86#define FDATA __SYSREG(0xd8f00030, u32)
87/* access pulse register */
88#define FPWS __SYSREG(0xd8f00100, u32)
89#define FPWS_PWS1W_2CLK 0x00000000 /* write pulse width 1clock */
90#define FPWS_PWS1W_3CLK 0x01000000 /* write pulse width 2clock */
91#define FPWS_PWS1W_4CLK 0x02000000 /* write pulse width 4clock */
92#define FPWS_PWS1W_5CLK 0x03000000 /* write pulse width 5clock */
93#define FPWS_PWS1W_6CLK 0x04000000 /* write pulse width 6clock */
94#define FPWS_PWS1W_7CLK 0x05000000 /* write pulse width 7clock */
95#define FPWS_PWS1W_8CLK 0x06000000 /* write pulse width 8clock */
96#define FPWS_PWS1R_3CLK 0x00010000 /* read pulse width 3clock */
97#define FPWS_PWS1R_4CLK 0x00020000 /* read pulse width 4clock */
98#define FPWS_PWS1R_5CLK 0x00030000 /* read pulse width 5clock */
99#define FPWS_PWS1R_6CLK 0x00040000 /* read pulse width 6clock */
100#define FPWS_PWS1R_7CLK 0x00050000 /* read pulse width 7clock */
101#define FPWS_PWS1R_8CLK 0x00060000 /* read pulse width 8clock */
102#define FPWS_PWS2W_2CLK 0x00000100 /* write pulse interval 2clock */
103#define FPWS_PWS2W_3CLK 0x00000200 /* write pulse interval 3clock */
104#define FPWS_PWS2W_4CLK 0x00000300 /* write pulse interval 4clock */
105#define FPWS_PWS2W_5CLK 0x00000400 /* write pulse interval 5clock */
106#define FPWS_PWS2W_6CLK 0x00000500 /* write pulse interval 6clock */
107#define FPWS_PWS2R_2CLK 0x00000001 /* read pulse interval 2clock */
108#define FPWS_PWS2R_3CLK 0x00000002 /* read pulse interval 3clock */
109#define FPWS_PWS2R_4CLK 0x00000003 /* read pulse interval 4clock */
110#define FPWS_PWS2R_5CLK 0x00000004 /* read pulse interval 5clock */
111#define FPWS_PWS2R_6CLK 0x00000005 /* read pulse interval 6clock */
112/* command register 2 */
113#define FCOMMAND2 __SYSREG(0xd8f00110, u32)
114/* transfer frequency register */
115#define FNUM __SYSREG(0xd8f00114, u32)
116#define FSDATA_ADDR 0xd8f00400
117/* active data register */
118#define FSDATA __SYSREG(FSDATA_ADDR, u32)
119
120#endif /* _PROC_NAND_REGS_H_ */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/proc.h b/arch/mn10300/proc-mn2ws0050/include/proc/proc.h
new file mode 100644
index 000000000000..90d5cadd05bd
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/proc.h
@@ -0,0 +1,18 @@
1/* proc.h: MN2WS0050 processor description
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _ASM_PROC_PROC_H
13#define _ASM_PROC_PROC_H
14
15#define PROCESSOR_VENDOR_NAME "Panasonic"
16#define PROCESSOR_MODEL_NAME "mn2ws0050"
17
18#endif /* _ASM_PROC_PROC_H */
diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h
new file mode 100644
index 000000000000..22f277fbb4de
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/include/proc/smp-regs.h
@@ -0,0 +1,51 @@
1/* MN10300/AM33v2 Microcontroller SMP registers
2 *
3 * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
4 * All Rights Reserved.
5 * Created:
6 * 13-Nov-2006 MEI Add extended cache and atomic operation register
7 * for SMP support.
8 * 23-Feb-2007 MEI Add define for gdbstub SMP.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#ifndef _ASM_PROC_SMP_REGS_H
17#define _ASM_PROC_SMP_REGS_H
18
19#ifdef __KERNEL__
20
21#ifndef __ASSEMBLY__
22#include <linux/types.h>
23#endif
24#include <asm/cpu-regs.h>
25
26/*
27 * Reference to the interrupt controllers of other CPUs
28 */
29#define CROSS_ICR_CPU_SHIFT 16
30
31#define CROSS_GxICR(X, CPU) __SYSREG(0xc4000000 + (X) * 4 + \
32 ((X) >= 64 && (X) < 192) * 0xf00 + ((CPU) << CROSS_ICR_CPU_SHIFT), u16)
33#define CROSS_GxICR_u8(X, CPU) __SYSREG(0xc4000000 + (X) * 4 + \
34 (((X) >= 64) && ((X) < 192)) * 0xf00 + ((CPU) << CROSS_ICR_CPU_SHIFT), u8)
35
36/* CPU ID register */
37#define CPUID __SYSREGC(0xc0000054, u32)
38#define CPUID_MASK 0x00000007 /* CPU ID mask */
39
40/* extended cache control register */
41#define ECHCTR __SYSREG(0xc0000c20, u32)
42#define ECHCTR_IBCM 0x00000001 /* instruction cache broad cast mask */
43#define ECHCTR_DBCM 0x00000002 /* data cache broad cast mask */
44#define ECHCTR_ISPM 0x00000004 /* instruction cache snoop mask */
45#define ECHCTR_DSPM 0x00000008 /* data cache snoop mask */
46
47#define NMIAGR __SYSREG(0xd400013c, u16)
48#define NMIAGR_GN 0x03fc
49
50#endif /* __KERNEL__ */
51#endif /* _ASM_PROC_SMP_REGS_H */
diff --git a/arch/mn10300/proc-mn2ws0050/proc-init.c b/arch/mn10300/proc-mn2ws0050/proc-init.c
new file mode 100644
index 000000000000..c58249b9525a
--- /dev/null
+++ b/arch/mn10300/proc-mn2ws0050/proc-init.c
@@ -0,0 +1,134 @@
1/* MN2WS0050 processor initialisation
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/sched.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/interrupt.h>
16
17#include <asm/processor.h>
18#include <asm/system.h>
19#include <asm/uaccess.h>
20#include <asm/io.h>
21#include <asm/atomic.h>
22#include <asm/smp.h>
23#include <asm/pgalloc.h>
24#include <asm/busctl-regs.h>
25#include <unit/timex.h>
26#include <asm/fpu.h>
27#include <asm/rtc.h>
28
29#define MEMCONF __SYSREGC(0xdf800400, u32)
30
31/*
32 * initialise the on-silicon processor peripherals
33 */
34asmlinkage void __init processor_init(void)
35{
36 int loop;
37
38 /* set up the exception table first */
39 for (loop = 0x000; loop < 0x400; loop += 8)
40 __set_intr_stub(loop, __common_exception);
41
42 __set_intr_stub(EXCEP_ITLBMISS, itlb_miss);
43 __set_intr_stub(EXCEP_DTLBMISS, dtlb_miss);
44 __set_intr_stub(EXCEP_IAERROR, itlb_aerror);
45 __set_intr_stub(EXCEP_DAERROR, dtlb_aerror);
46 __set_intr_stub(EXCEP_BUSERROR, raw_bus_error);
47 __set_intr_stub(EXCEP_DOUBLE_FAULT, double_fault);
48 __set_intr_stub(EXCEP_FPU_DISABLED, fpu_disabled);
49 __set_intr_stub(EXCEP_SYSCALL0, system_call);
50
51 __set_intr_stub(EXCEP_NMI, nmi_handler);
52 __set_intr_stub(EXCEP_WDT, nmi_handler);
53 __set_intr_stub(EXCEP_IRQ_LEVEL0, irq_handler);
54 __set_intr_stub(EXCEP_IRQ_LEVEL1, irq_handler);
55 __set_intr_stub(EXCEP_IRQ_LEVEL2, irq_handler);
56 __set_intr_stub(EXCEP_IRQ_LEVEL3, irq_handler);
57 __set_intr_stub(EXCEP_IRQ_LEVEL4, irq_handler);
58 __set_intr_stub(EXCEP_IRQ_LEVEL5, irq_handler);
59 __set_intr_stub(EXCEP_IRQ_LEVEL6, irq_handler);
60
61 IVAR0 = EXCEP_IRQ_LEVEL0;
62 IVAR1 = EXCEP_IRQ_LEVEL1;
63 IVAR2 = EXCEP_IRQ_LEVEL2;
64 IVAR3 = EXCEP_IRQ_LEVEL3;
65 IVAR4 = EXCEP_IRQ_LEVEL4;
66 IVAR5 = EXCEP_IRQ_LEVEL5;
67 IVAR6 = EXCEP_IRQ_LEVEL6;
68
69#ifndef CONFIG_MN10300_HAS_CACHE_SNOOP
70 mn10300_dcache_flush_inv();
71 mn10300_icache_inv();
72#endif
73
74 /* disable all interrupts and set to priority 6 (lowest) */
75#ifdef CONFIG_SMP
76 for (loop = 0; loop < GxICR_NUM_IRQS; loop++)
77 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
78#else /* !CONFIG_SMP */
79 for (loop = 0; loop < NR_IRQS; loop++)
80 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
81#endif /* !CONFIG_SMP */
82
83 /* clear the timers */
84 TM0MD = 0;
85 TM1MD = 0;
86 TM2MD = 0;
87 TM3MD = 0;
88 TM4MD = 0;
89 TM5MD = 0;
90 TM6MD = 0;
91 TM6MDA = 0;
92 TM6MDB = 0;
93 TM7MD = 0;
94 TM8MD = 0;
95 TM9MD = 0;
96 TM10MD = 0;
97 TM11MD = 0;
98 TM12MD = 0;
99 TM13MD = 0;
100 TM14MD = 0;
101 TM15MD = 0;
102
103 calibrate_clock();
104}
105
106/*
107 * determine the memory size and base from the memory controller regs
108 */
109void __init get_mem_info(unsigned long *mem_base, unsigned long *mem_size)
110{
111 unsigned long memconf = MEMCONF;
112 unsigned long size = 0; /* order: MByte */
113
114 *mem_base = 0x90000000; /* fixed address */
115
116 switch (memconf & 0x00000003) {
117 case 0x01:
118 size = 256 / 8; /* 256 Mbit per chip */
119 break;
120 case 0x02:
121 size = 512 / 8; /* 512 Mbit per chip */
122 break;
123 case 0x03:
124 size = 1024 / 8; /* 1 Gbit per chip */
125 break;
126 default:
127 panic("Invalid SDRAM size");
128 break;
129 }
130
131 printk(KERN_INFO "DDR2-SDRAM: %luMB x 2 @%08lx\n", size, *mem_base);
132
133 *mem_size = (size * 2) << 20;
134}
diff --git a/arch/mn10300/unit-asb2303/include/unit/clock.h b/arch/mn10300/unit-asb2303/include/unit/clock.h
index 2a0bf79ab968..0316907a012e 100644
--- a/arch/mn10300/unit-asb2303/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2303/include/unit/clock.h
@@ -14,32 +14,11 @@
14 14
15#ifndef __ASSEMBLY__ 15#ifndef __ASSEMBLY__
16 16
17#ifdef CONFIG_MN10300_RTC
18
19extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
20extern unsigned long mn10300_iobclk;
21extern unsigned long mn10300_tsc_per_HZ;
22
23#define MN10300_IOCLK mn10300_ioclk
24/* If this processors has a another clock, uncomment the below. */
25/* #define MN10300_IOBCLK mn10300_iobclk */
26
27#else /* !CONFIG_MN10300_RTC */
28
29#define MN10300_IOCLK 33333333UL 17#define MN10300_IOCLK 33333333UL
30/* #define MN10300_IOBCLK 66666666UL */ 18/* #define MN10300_IOBCLK 66666666UL */
31 19
32#endif /* !CONFIG_MN10300_RTC */
33
34#define MN10300_JCCLK MN10300_IOCLK
35#define MN10300_TSCCLK MN10300_IOCLK
36
37#ifdef CONFIG_MN10300_RTC
38#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
39#else /* !CONFIG_MN10300_RTC */
40#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
41#endif /* !CONFIG_MN10300_RTC */
42
43#endif /* !__ASSEMBLY__ */ 20#endif /* !__ASSEMBLY__ */
44 21
22#define MN10300_WDCLK MN10300_IOCLK
23
45#endif /* _ASM_UNIT_CLOCK_H */ 24#endif /* _ASM_UNIT_CLOCK_H */
diff --git a/arch/mn10300/unit-asb2303/include/unit/serial.h b/arch/mn10300/unit-asb2303/include/unit/serial.h
index 047566cd2e36..991e356bac5f 100644
--- a/arch/mn10300/unit-asb2303/include/unit/serial.h
+++ b/arch/mn10300/unit-asb2303/include/unit/serial.h
@@ -22,6 +22,11 @@
22#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */ 22#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */
23 23
24/* 24/*
25 * The ASB2303 has an 18.432 MHz clock the UART
26 */
27#define BASE_BAUD (18432000 / 16)
28
29/*
25 * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports 30 * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports
26 */ 31 */
27#ifndef CONFIG_GDBSTUB_ON_TTYSx 32#ifndef CONFIG_GDBSTUB_ON_TTYSx
diff --git a/arch/mn10300/unit-asb2303/include/unit/timex.h b/arch/mn10300/unit-asb2303/include/unit/timex.h
index 88cd96bb2527..d1b8dafe7d7d 100644
--- a/arch/mn10300/unit-asb2303/include/unit/timex.h
+++ b/arch/mn10300/unit-asb2303/include/unit/timex.h
@@ -1,4 +1,4 @@
1/* ASB2303-specific timer specifcations 1/* ASB2303-specific timer specifications
2 * 2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -17,6 +17,7 @@
17 17
18#include <asm/timer-regs.h> 18#include <asm/timer-regs.h>
19#include <unit/clock.h> 19#include <unit/clock.h>
20#include <asm/param.h>
20 21
21/* 22/*
22 * jiffies counter specifications 23 * jiffies counter specifications
@@ -29,32 +30,43 @@
29#define TMJCBR TM01BR 30#define TMJCBR TM01BR
30#define TMJCIRQ TM1IRQ 31#define TMJCIRQ TM1IRQ
31#define TMJCICR TM1ICR 32#define TMJCICR TM1ICR
32#define TMJCICR_LEVEL GxICR_LEVEL_5
33 33
34#ifndef __ASSEMBLY__ 34#ifndef __ASSEMBLY__
35 35
36#define MN10300_SRC_IOCLK MN10300_IOCLK
37
38#ifndef HZ
39# error HZ undeclared.
40#endif /* !HZ */
41/* use as little prescaling as possible to avoid losing accuracy */
42#if (MN10300_SRC_IOCLK + HZ / 2) / HZ - 1 <= TMJCBR_MAX
43# define IOCLK_PRESCALE 1
44# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK
45# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK
46#elif (MN10300_SRC_IOCLK / 8 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
47# define IOCLK_PRESCALE 8
48# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_8
49# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_8
50#elif (MN10300_SRC_IOCLK / 32 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
51# define IOCLK_PRESCALE 32
52# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_32
53# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_32
54#else
55# error You lose.
56#endif
57
58#define MN10300_JCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
59#define MN10300_TSCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
60
61#define MN10300_JC_PER_HZ ((MN10300_JCCLK + HZ / 2) / HZ)
62#define MN10300_TSC_PER_HZ ((MN10300_TSCCLK + HZ / 2) / HZ)
63
36static inline void startup_jiffies_counter(void) 64static inline void startup_jiffies_counter(void)
37{ 65{
38 unsigned rate;
39 u16 md, t16; 66 u16 md, t16;
40 67
41 /* use as little prescaling as possible to avoid losing accuracy */ 68 md = JC_TIMER_CLKSRC;
42 md = TM0MD_SRC_IOCLK; 69 TMJCBR = MN10300_JC_PER_HZ - 1;
43 rate = MN10300_JCCLK / HZ;
44
45 if (rate > TMJCBR_MAX) {
46 md = TM0MD_SRC_IOCLK_8;
47 rate = MN10300_JCCLK / 8 / HZ;
48
49 if (rate > TMJCBR_MAX) {
50 md = TM0MD_SRC_IOCLK_32;
51 rate = MN10300_JCCLK / 32 / HZ;
52
53 BUG_ON(rate > TMJCBR_MAX);
54 }
55 }
56
57 TMJCBR = rate - 1;
58 t16 = TMJCBR; 70 t16 = TMJCBR;
59 71
60 TMJCMD = 72 TMJCMD =
@@ -93,29 +105,39 @@ static inline void shutdown_jiffies_counter(void)
93 105
94static inline void startup_timestamp_counter(void) 106static inline void startup_timestamp_counter(void)
95{ 107{
108 u32 t32;
109
96 /* set up timer 4 & 5 cascaded as a 32-bit counter to count real time 110 /* set up timer 4 & 5 cascaded as a 32-bit counter to count real time
97 * - count down from 4Gig-1 to 0 and wrap at IOCLK rate 111 * - count down from 4Gig-1 to 0 and wrap at IOCLK rate
98 */ 112 */
99 TM45BR = TMTSCBR_MAX; 113 TM45BR = TMTSCBR_MAX;
114 t32 = TM45BR;
100 115
101 TM4MD = TM4MD_SRC_IOCLK; 116 TM4MD = TSC_TIMER_CLKSRC;
102 TM4MD |= TM4MD_INIT_COUNTER; 117 TM4MD |= TM4MD_INIT_COUNTER;
103 TM4MD &= ~TM4MD_INIT_COUNTER; 118 TM4MD &= ~TM4MD_INIT_COUNTER;
104 TM4ICR = 0; 119 TM4ICR = 0;
120 t32 = TM4ICR;
105 121
106 TM5MD = TM5MD_SRC_TM4CASCADE; 122 TM5MD = TM5MD_SRC_TM4CASCADE;
107 TM5MD |= TM5MD_INIT_COUNTER; 123 TM5MD |= TM5MD_INIT_COUNTER;
108 TM5MD &= ~TM5MD_INIT_COUNTER; 124 TM5MD &= ~TM5MD_INIT_COUNTER;
109 TM5ICR = 0; 125 TM5ICR = 0;
126 t32 = TM5ICR;
110 127
111 TM5MD |= TM5MD_COUNT_ENABLE; 128 TM5MD |= TM5MD_COUNT_ENABLE;
112 TM4MD |= TM4MD_COUNT_ENABLE; 129 TM4MD |= TM4MD_COUNT_ENABLE;
130 t32 = TM5MD;
131 t32 = TM4MD;
113} 132}
114 133
115static inline void shutdown_timestamp_counter(void) 134static inline void shutdown_timestamp_counter(void)
116{ 135{
136 u8 t8;
117 TM4MD = 0; 137 TM4MD = 0;
118 TM5MD = 0; 138 TM5MD = 0;
139 t8 = TM4MD;
140 t8 = TM5MD;
119} 141}
120 142
121/* 143/*
diff --git a/arch/mn10300/unit-asb2303/unit-init.c b/arch/mn10300/unit-asb2303/unit-init.c
index 70e8cb4ea266..834a76aa551a 100644
--- a/arch/mn10300/unit-asb2303/unit-init.c
+++ b/arch/mn10300/unit-asb2303/unit-init.c
@@ -31,6 +31,14 @@ asmlinkage void __init unit_init(void)
31 SET_XIRQ_TRIGGER(3, XIRQ_TRIGGER_HILEVEL); 31 SET_XIRQ_TRIGGER(3, XIRQ_TRIGGER_HILEVEL);
32 SET_XIRQ_TRIGGER(4, XIRQ_TRIGGER_LOWLEVEL); 32 SET_XIRQ_TRIGGER(4, XIRQ_TRIGGER_LOWLEVEL);
33 SET_XIRQ_TRIGGER(5, XIRQ_TRIGGER_LOWLEVEL); 33 SET_XIRQ_TRIGGER(5, XIRQ_TRIGGER_LOWLEVEL);
34
35#ifdef CONFIG_EXT_SERIAL_IRQ_LEVEL
36 set_intr_level(XIRQ0, NUM2GxICR_LEVEL(CONFIG_EXT_SERIAL_IRQ_LEVEL));
37#endif
38
39#ifdef CONFIG_ETHERNET_IRQ_LEVEL
40 set_intr_level(XIRQ3, NUM2GxICR_LEVEL(CONFIG_ETHERNET_IRQ_LEVEL));
41#endif
34} 42}
35 43
36/* 44/*
@@ -51,7 +59,7 @@ void __init unit_init_IRQ(void)
51 switch (GET_XIRQ_TRIGGER(extnum)) { 59 switch (GET_XIRQ_TRIGGER(extnum)) {
52 case XIRQ_TRIGGER_HILEVEL: 60 case XIRQ_TRIGGER_HILEVEL:
53 case XIRQ_TRIGGER_LOWLEVEL: 61 case XIRQ_TRIGGER_LOWLEVEL:
54 set_intr_postackable(XIRQ2IRQ(extnum)); 62 mn10300_set_lateack_irq_type(XIRQ2IRQ(extnum));
55 break; 63 break;
56 default: 64 default:
57 break; 65 break;
diff --git a/arch/mn10300/unit-asb2305/include/unit/clock.h b/arch/mn10300/unit-asb2305/include/unit/clock.h
index 67be3f2eb18e..29e3425431cf 100644
--- a/arch/mn10300/unit-asb2305/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2305/include/unit/clock.h
@@ -14,32 +14,11 @@
14 14
15#ifndef __ASSEMBLY__ 15#ifndef __ASSEMBLY__
16 16
17#ifdef CONFIG_MN10300_RTC
18
19extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
20extern unsigned long mn10300_iobclk;
21extern unsigned long mn10300_tsc_per_HZ;
22
23#define MN10300_IOCLK mn10300_ioclk
24/* If this processors has a another clock, uncomment the below. */
25/* #define MN10300_IOBCLK mn10300_iobclk */
26
27#else /* !CONFIG_MN10300_RTC */
28
29#define MN10300_IOCLK 33333333UL 17#define MN10300_IOCLK 33333333UL
30/* #define MN10300_IOBCLK 66666666UL */ 18/* #define MN10300_IOBCLK 66666666UL */
31 19
32#endif /* !CONFIG_MN10300_RTC */
33
34#define MN10300_JCCLK MN10300_IOCLK
35#define MN10300_TSCCLK MN10300_IOCLK
36
37#ifdef CONFIG_MN10300_RTC
38#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
39#else /* !CONFIG_MN10300_RTC */
40#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
41#endif /* !CONFIG_MN10300_RTC */
42
43#endif /* !__ASSEMBLY__ */ 20#endif /* !__ASSEMBLY__ */
44 21
22#define MN10300_WDCLK MN10300_IOCLK
23
45#endif /* _ASM_UNIT_CLOCK_H */ 24#endif /* _ASM_UNIT_CLOCK_H */
diff --git a/arch/mn10300/unit-asb2305/include/unit/serial.h b/arch/mn10300/unit-asb2305/include/unit/serial.h
index 8086cc092cec..88c08219315f 100644
--- a/arch/mn10300/unit-asb2305/include/unit/serial.h
+++ b/arch/mn10300/unit-asb2305/include/unit/serial.h
@@ -21,6 +21,11 @@
21#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */ 21#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */
22 22
23/* 23/*
24 * The ASB2305 has an 18.432 MHz clock the UART
25 */
26#define BASE_BAUD (18432000 / 16)
27
28/*
24 * dispose of the /dev/ttyS0 serial port 29 * dispose of the /dev/ttyS0 serial port
25 */ 30 */
26#ifndef CONFIG_GDBSTUB_ON_TTYSx 31#ifndef CONFIG_GDBSTUB_ON_TTYSx
diff --git a/arch/mn10300/unit-asb2305/include/unit/timex.h b/arch/mn10300/unit-asb2305/include/unit/timex.h
index 0860186eedb2..cd8bc14e3ca3 100644
--- a/arch/mn10300/unit-asb2305/include/unit/timex.h
+++ b/arch/mn10300/unit-asb2305/include/unit/timex.h
@@ -1,4 +1,4 @@
1/* ASB2305 timer specifcations 1/* ASB2305-specific timer specifications
2 * 2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -17,6 +17,7 @@
17 17
18#include <asm/timer-regs.h> 18#include <asm/timer-regs.h>
19#include <unit/clock.h> 19#include <unit/clock.h>
20#include <asm/param.h>
20 21
21/* 22/*
22 * jiffies counter specifications 23 * jiffies counter specifications
@@ -29,32 +30,43 @@
29#define TMJCBR TM01BR 30#define TMJCBR TM01BR
30#define TMJCIRQ TM1IRQ 31#define TMJCIRQ TM1IRQ
31#define TMJCICR TM1ICR 32#define TMJCICR TM1ICR
32#define TMJCICR_LEVEL GxICR_LEVEL_5
33 33
34#ifndef __ASSEMBLY__ 34#ifndef __ASSEMBLY__
35 35
36#define MN10300_SRC_IOCLK MN10300_IOCLK
37
38#ifndef HZ
39# error HZ undeclared.
40#endif /* !HZ */
41/* use as little prescaling as possible to avoid losing accuracy */
42#if (MN10300_SRC_IOCLK + HZ / 2) / HZ - 1 <= TMJCBR_MAX
43# define IOCLK_PRESCALE 1
44# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK
45# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK
46#elif (MN10300_SRC_IOCLK / 8 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
47# define IOCLK_PRESCALE 8
48# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_8
49# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_8
50#elif (MN10300_SRC_IOCLK / 32 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
51# define IOCLK_PRESCALE 32
52# define JC_TIMER_CLKSRC TM0MD_SRC_IOCLK_32
53# define TSC_TIMER_CLKSRC TM4MD_SRC_IOCLK_32
54#else
55# error You lose.
56#endif
57
58#define MN10300_JCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
59#define MN10300_TSCCLK (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
60
61#define MN10300_JC_PER_HZ ((MN10300_JCCLK + HZ / 2) / HZ)
62#define MN10300_TSC_PER_HZ ((MN10300_TSCCLK + HZ / 2) / HZ)
63
36static inline void startup_jiffies_counter(void) 64static inline void startup_jiffies_counter(void)
37{ 65{
38 unsigned rate;
39 u16 md, t16; 66 u16 md, t16;
40 67
41 /* use as little prescaling as possible to avoid losing accuracy */ 68 md = JC_TIMER_CLKSRC;
42 md = TM0MD_SRC_IOCLK; 69 TMJCBR = MN10300_JC_PER_HZ - 1;
43 rate = MN10300_JCCLK / HZ;
44
45 if (rate > TMJCBR_MAX) {
46 md = TM0MD_SRC_IOCLK_8;
47 rate = MN10300_JCCLK / 8 / HZ;
48
49 if (rate > TMJCBR_MAX) {
50 md = TM0MD_SRC_IOCLK_32;
51 rate = MN10300_JCCLK / 32 / HZ;
52
53 BUG_ON(rate > TMJCBR_MAX);
54 }
55 }
56
57 TMJCBR = rate - 1;
58 t16 = TMJCBR; 70 t16 = TMJCBR;
59 71
60 TMJCMD = 72 TMJCMD =
@@ -93,29 +105,39 @@ static inline void shutdown_jiffies_counter(void)
93 105
94static inline void startup_timestamp_counter(void) 106static inline void startup_timestamp_counter(void)
95{ 107{
108 u32 t32;
109
96 /* set up timer 4 & 5 cascaded as a 32-bit counter to count real time 110 /* set up timer 4 & 5 cascaded as a 32-bit counter to count real time
97 * - count down from 4Gig-1 to 0 and wrap at IOCLK rate 111 * - count down from 4Gig-1 to 0 and wrap at IOCLK rate
98 */ 112 */
99 TM45BR = TMTSCBR_MAX; 113 TM45BR = TMTSCBR_MAX;
114 t32 = TM45BR;
100 115
101 TM4MD = TM4MD_SRC_IOCLK; 116 TM4MD = TSC_TIMER_CLKSRC;
102 TM4MD |= TM4MD_INIT_COUNTER; 117 TM4MD |= TM4MD_INIT_COUNTER;
103 TM4MD &= ~TM4MD_INIT_COUNTER; 118 TM4MD &= ~TM4MD_INIT_COUNTER;
104 TM4ICR = 0; 119 TM4ICR = 0;
120 t32 = TM4ICR;
105 121
106 TM5MD = TM5MD_SRC_TM4CASCADE; 122 TM5MD = TM5MD_SRC_TM4CASCADE;
107 TM5MD |= TM5MD_INIT_COUNTER; 123 TM5MD |= TM5MD_INIT_COUNTER;
108 TM5MD &= ~TM5MD_INIT_COUNTER; 124 TM5MD &= ~TM5MD_INIT_COUNTER;
109 TM5ICR = 0; 125 TM5ICR = 0;
126 t32 = TM5ICR;
110 127
111 TM5MD |= TM5MD_COUNT_ENABLE; 128 TM5MD |= TM5MD_COUNT_ENABLE;
112 TM4MD |= TM4MD_COUNT_ENABLE; 129 TM4MD |= TM4MD_COUNT_ENABLE;
130 t32 = TM5MD;
131 t32 = TM4MD;
113} 132}
114 133
115static inline void shutdown_timestamp_counter(void) 134static inline void shutdown_timestamp_counter(void)
116{ 135{
136 u8 t8;
117 TM4MD = 0; 137 TM4MD = 0;
118 TM5MD = 0; 138 TM5MD = 0;
139 t8 = TM4MD;
140 t8 = TM5MD;
119} 141}
120 142
121/* 143/*
@@ -126,7 +148,7 @@ typedef unsigned long cycles_t;
126 148
127static inline cycles_t read_timestamp_counter(void) 149static inline cycles_t read_timestamp_counter(void)
128{ 150{
129 return (cycles_t) TMTSCBC; 151 return (cycles_t)TMTSCBC;
130} 152}
131 153
132#endif /* !__ASSEMBLY__ */ 154#endif /* !__ASSEMBLY__ */
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index 6d8720a0a599..a4954fe82094 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -503,7 +503,7 @@ asmlinkage void __init unit_pci_init(void)
503 struct pci_ops *o = &pci_direct_ampci; 503 struct pci_ops *o = &pci_direct_ampci;
504 u32 x; 504 u32 x;
505 505
506 set_intr_level(XIRQ1, GxICR_LEVEL_3); 506 set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_PCI_IRQ_LEVEL));
507 507
508 memset(&bus, 0, sizeof(bus)); 508 memset(&bus, 0, sizeof(bus));
509 509
diff --git a/arch/mn10300/unit-asb2305/unit-init.c b/arch/mn10300/unit-asb2305/unit-init.c
index a76c8e0ab90f..e1becd6b7571 100644
--- a/arch/mn10300/unit-asb2305/unit-init.c
+++ b/arch/mn10300/unit-asb2305/unit-init.c
@@ -26,8 +26,10 @@ asmlinkage void __init unit_init(void)
26{ 26{
27#ifndef CONFIG_GDBSTUB_ON_TTYSx 27#ifndef CONFIG_GDBSTUB_ON_TTYSx
28 /* set the 16550 interrupt line to level 3 if not being used for GDB */ 28 /* set the 16550 interrupt line to level 3 if not being used for GDB */
29 set_intr_level(XIRQ0, GxICR_LEVEL_3); 29#ifdef CONFIG_EXT_SERIAL_IRQ_LEVEL
30 set_intr_level(XIRQ0, NUM2GxICR_LEVEL(CONFIG_EXT_SERIAL_IRQ_LEVEL));
30#endif 31#endif
32#endif /* CONFIG_GDBSTUB_ON_TTYSx */
31} 33}
32 34
33/* 35/*
@@ -51,7 +53,7 @@ void __init unit_init_IRQ(void)
51 switch (GET_XIRQ_TRIGGER(extnum)) { 53 switch (GET_XIRQ_TRIGGER(extnum)) {
52 case XIRQ_TRIGGER_HILEVEL: 54 case XIRQ_TRIGGER_HILEVEL:
53 case XIRQ_TRIGGER_LOWLEVEL: 55 case XIRQ_TRIGGER_LOWLEVEL:
54 set_intr_postackable(XIRQ2IRQ(extnum)); 56 mn10300_set_lateack_irq_type(XIRQ2IRQ(extnum));
55 break; 57 break;
56 default: 58 default:
57 break; 59 break;
diff --git a/arch/mn10300/unit-asb2364/Makefile b/arch/mn10300/unit-asb2364/Makefile
new file mode 100644
index 000000000000..6dd27d65877a
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for the linux kernel.
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8# Note 2! The CFLAGS definitions are now in the main makefile...
9
10obj-y := unit-init.o leds.o
diff --git a/arch/mn10300/unit-asb2364/include/unit/clock.h b/arch/mn10300/unit-asb2364/include/unit/clock.h
new file mode 100644
index 000000000000..d34ac9a7508b
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/clock.h
@@ -0,0 +1,29 @@
1/* clock.h: unit-specific clocks
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * Modified by Matsushita Electric Industrial Co., Ltd.
7 * Modifications:
8 * 23-Feb-2007 MEI Add define for watchdog timer.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#ifndef _ASM_UNIT_CLOCK_H
17#define _ASM_UNIT_CLOCK_H
18
19#ifndef __ASSEMBLY__
20
21#define MN10300_IOCLK 100000000UL /* for DDR800 */
22/*#define MN10300_IOCLK 83333333UL */ /* for DDR667 */
23#define MN10300_IOBCLK MN10300_IOCLK /* IOBCLK is equal to IOCLK */
24
25#endif /* !__ASSEMBLY__ */
26
27#define MN10300_WDCLK 27000000UL
28
29#endif /* _ASM_UNIT_CLOCK_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h b/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h
new file mode 100644
index 000000000000..a039a50c91db
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h
@@ -0,0 +1,50 @@
1/* ASB2364 FPGA registers
2 */
3
4#ifndef _ASM_UNIT_FPGA_REGS_H
5#define _ASM_UNIT_FPGA_REGS_H
6
7#include <asm/cpu-regs.h>
8
9#ifdef __KERNEL__
10
11#define ASB2364_FPGA_REG_RESET_LAN __SYSREG(0xa9001300, u16)
12#define ASB2364_FPGA_REG_RESET_UART __SYSREG(0xa9001304, u16)
13#define ASB2364_FPGA_REG_RESET_I2C __SYSREG(0xa9001308, u16)
14#define ASB2364_FPGA_REG_RESET_USB __SYSREG(0xa900130c, u16)
15#define ASB2364_FPGA_REG_RESET_AV __SYSREG(0xa9001310, u16)
16
17#define ASB2364_FPGA_REG_IRQ_LAN __SYSREG(0xa9001510, u16)
18#define ASB2364_FPGA_REG_IRQ_UART __SYSREG(0xa9001514, u16)
19#define ASB2364_FPGA_REG_IRQ_I2C __SYSREG(0xa9001518, u16)
20#define ASB2364_FPGA_REG_IRQ_USB __SYSREG(0xa900151c, u16)
21#define ASB2364_FPGA_REG_IRQ_FPGA __SYSREG(0xa9001524, u16)
22
23#define ASB2364_FPGA_REG_MASK_LAN __SYSREG(0xa9001590, u16)
24#define ASB2364_FPGA_REG_MASK_UART __SYSREG(0xa9001594, u16)
25#define ASB2364_FPGA_REG_MASK_I2C __SYSREG(0xa9001598, u16)
26#define ASB2364_FPGA_REG_MASK_USB __SYSREG(0xa900159c, u16)
27#define ASB2364_FPGA_REG_MASK_FPGA __SYSREG(0xa90015a4, u16)
28
29#define ASB2364_FPGA_REG_CPLD5_SET1 __SYSREG(0xa9002500, u16)
30#define ASB2364_FPGA_REG_CPLD5_SET2 __SYSREG(0xa9002504, u16)
31#define ASB2364_FPGA_REG_CPLD6_SET1 __SYSREG(0xa9002600, u16)
32#define ASB2364_FPGA_REG_CPLD6_SET2 __SYSREG(0xa9002604, u16)
33#define ASB2364_FPGA_REG_CPLD7_SET1 __SYSREG(0xa9002700, u16)
34#define ASB2364_FPGA_REG_CPLD7_SET2 __SYSREG(0xa9002704, u16)
35#define ASB2364_FPGA_REG_CPLD8_SET1 __SYSREG(0xa9002800, u16)
36#define ASB2364_FPGA_REG_CPLD8_SET2 __SYSREG(0xa9002804, u16)
37#define ASB2364_FPGA_REG_CPLD9_SET1 __SYSREG(0xa9002900, u16)
38#define ASB2364_FPGA_REG_CPLD9_SET2 __SYSREG(0xa9002904, u16)
39#define ASB2364_FPGA_REG_CPLD10_SET1 __SYSREG(0xa9002a00, u16)
40#define ASB2364_FPGA_REG_CPLD10_SET2 __SYSREG(0xa9002a04, u16)
41
42#define SyncExBus() \
43 do { \
44 unsigned short w; \
45 w = *(volatile short *)0xa9000000; \
46 } while (0)
47
48#endif /* __KERNEL__ */
49
50#endif /* _ASM_UNIT_FPGA_REGS_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/leds.h b/arch/mn10300/unit-asb2364/include/unit/leds.h
new file mode 100644
index 000000000000..03a3933ad323
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/leds.h
@@ -0,0 +1,54 @@
1/* Unit-specific leds
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _ASM_UNIT_LEDS_H
13#define _ASM_UNIT_LEDS_H
14
15#include <asm/pio-regs.h>
16#include <asm/cpu-regs.h>
17#include <asm/exceptions.h>
18
19#define MN10300_USE_7SEGLEDS 0
20
21#define ASB2364_7SEGLEDS __SYSREG(0xA9001630, u32)
22
23/*
24 * use the 7-segment LEDs to indicate states
25 */
26
27#if MN10300_USE_7SEGLEDS
28/* flip the 7-segment LEDs between "Gdb-" and "----" */
29#define mn10300_set_gdbleds(ONOFF) \
30 do { \
31 ASB2364_7SEGLEDS = (ONOFF) ? 0x8543077f : 0x7f7f7f7f; \
32 } while (0)
33#else
34#define mn10300_set_gdbleds(ONOFF) do {} while (0)
35#endif
36
37#if MN10300_USE_7SEGLEDS
38/* indicate double-fault by displaying "db-f" on the LEDs */
39#define mn10300_set_dbfleds \
40 mov 0x43077f1d,d0 ; \
41 mov d0,(ASB2364_7SEGLEDS)
42#else
43#define mn10300_set_dbfleds
44#endif
45
46#ifndef __ASSEMBLY__
47extern void peripheral_leds_display_exception(enum exception_code);
48extern void peripheral_leds_led_chase(void);
49extern void peripheral_leds7x4_display_dec(unsigned int, unsigned int);
50extern void peripheral_leds7x4_display_hex(unsigned int, unsigned int);
51extern void debug_to_serial(const char *, int);
52#endif /* __ASSEMBLY__ */
53
54#endif /* _ASM_UNIT_LEDS_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/serial.h b/arch/mn10300/unit-asb2364/include/unit/serial.h
new file mode 100644
index 000000000000..7f048bbfdfd7
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/serial.h
@@ -0,0 +1,151 @@
1/* Unit-specific 8250 serial ports
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _ASM_UNIT_SERIAL_H
13#define _ASM_UNIT_SERIAL_H
14
15#include <asm/cpu-regs.h>
16#include <proc/irq.h>
17#include <unit/fpga-regs.h>
18#include <linux/serial_reg.h>
19
20#define SERIAL_PORT0_BASE_ADDRESS 0xA8200000
21
22#define SERIAL_IRQ XIRQ1 /* single serial (TL16C550C) (Lo) */
23
24/*
25 * The ASB2364 has an 12.288 MHz clock
26 * for your UART.
27 *
28 * It'd be nice if someone built a serial card with a 24.576 MHz
29 * clock, since the 16550A is capable of handling a top speed of 1.5
30 * megabits/second; but this requires the faster clock.
31 */
32#define BASE_BAUD (12288000 / 16)
33
34/*
35 * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports
36 */
37#ifndef CONFIG_GDBSTUB_ON_TTYSx
38
39#define SERIAL_PORT_DFNS \
40 { \
41 .baud_base = BASE_BAUD, \
42 .irq = SERIAL_IRQ, \
43 .flags = STD_COM_FLAGS, \
44 .iomem_base = (u8 *) SERIAL_PORT0_BASE_ADDRESS, \
45 .iomem_reg_shift = 1, \
46 .io_type = SERIAL_IO_MEM, \
47 },
48
49#ifndef __ASSEMBLY__
50
51static inline void __debug_to_serial(const char *p, int n)
52{
53}
54
55#endif /* !__ASSEMBLY__ */
56
57#else /* CONFIG_GDBSTUB_ON_TTYSx */
58
59#define SERIAL_PORT_DFNS /* stolen by gdb-stub */
60
61#if defined(CONFIG_GDBSTUB_ON_TTYS0)
62#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX * 4, u8)
63#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8)
64#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8)
65#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8)
66#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8)
67#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8)
68#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8)
69#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8)
70#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8)
71#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8)
72#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8)
73#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8)
74#define GDBPORT_SERIAL_IRQ SERIAL_IRQ
75
76#elif defined(CONFIG_GDBSTUB_ON_TTYS1)
77#error The ASB2364 does not have a /dev/ttyS1
78#endif
79
80#ifndef __ASSEMBLY__
81
82static inline void __debug_to_serial(const char *p, int n)
83{
84 char ch;
85
86#define LSR_WAIT_FOR(STATE) \
87 do {} while (!(GDBPORT_SERIAL_LSR & UART_LSR_##STATE))
88#define FLOWCTL_QUERY(LINE) \
89 ({ GDBPORT_SERIAL_MSR & UART_MSR_##LINE; })
90#define FLOWCTL_WAIT_FOR(LINE) \
91 do {} while (!(GDBPORT_SERIAL_MSR & UART_MSR_##LINE))
92#define FLOWCTL_CLEAR(LINE) \
93 do { GDBPORT_SERIAL_MCR &= ~UART_MCR_##LINE; } while (0)
94#define FLOWCTL_SET(LINE) \
95 do { GDBPORT_SERIAL_MCR |= UART_MCR_##LINE; } while (0)
96
97 FLOWCTL_SET(DTR);
98
99 for (; n > 0; n--) {
100 LSR_WAIT_FOR(THRE);
101 FLOWCTL_WAIT_FOR(CTS);
102
103 ch = *p++;
104 if (ch == 0x0a) {
105 GDBPORT_SERIAL_TX = 0x0d;
106 LSR_WAIT_FOR(THRE);
107 FLOWCTL_WAIT_FOR(CTS);
108 }
109 GDBPORT_SERIAL_TX = ch;
110 }
111
112 FLOWCTL_CLEAR(DTR);
113}
114
115#endif /* !__ASSEMBLY__ */
116
117#endif /* CONFIG_GDBSTUB_ON_TTYSx */
118
119#define SERIAL_INITIALIZE \
120do { \
121 /* release reset */ \
122 ASB2364_FPGA_REG_RESET_UART = 0x0001; \
123 SyncExBus(); \
124} while (0)
125
126#define SERIAL_CHECK_INTERRUPT \
127do { \
128 if ((ASB2364_FPGA_REG_IRQ_UART & 0x0001) == 0x0001) { \
129 return IRQ_NONE; \
130 } \
131} while (0)
132
133#define SERIAL_CLEAR_INTERRUPT \
134do { \
135 ASB2364_FPGA_REG_IRQ_UART = 0x0001; \
136 SyncExBus(); \
137} while (0)
138
139#define SERIAL_SET_INT_MASK \
140do { \
141 ASB2364_FPGA_REG_MASK_UART = 0x0001; \
142 SyncExBus(); \
143} while (0)
144
145#define SERIAL_CLEAR_INT_MASK \
146do { \
147 ASB2364_FPGA_REG_MASK_UART = 0x0000; \
148 SyncExBus(); \
149} while (0)
150
151#endif /* _ASM_UNIT_SERIAL_H */
diff --git a/arch/mn10300/unit-asb2364/include/unit/timex.h b/arch/mn10300/unit-asb2364/include/unit/timex.h
new file mode 100644
index 000000000000..b5223f705ef8
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/timex.h
@@ -0,0 +1,125 @@
1/* timex.h: MN2WS0038 architecture timer specifications
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#ifndef _ASM_UNIT_TIMEX_H
12#define _ASM_UNIT_TIMEX_H
13
14#ifndef __ASSEMBLY__
15#include <linux/irq.h>
16#endif /* __ASSEMBLY__ */
17
18#include <asm/timer-regs.h>
19#include <unit/clock.h>
20#include <asm/param.h>
21
22/*
23 * jiffies counter specifications
24 */
25
26#define TMJCBR_MAX 0xffffff /* 24bit */
27#define TMJCBC TMTBC
28
29#define TMJCMD TMTMD
30#define TMJCBR TMTBR
31#define TMJCIRQ TMTIRQ
32#define TMJCICR TMTICR
33
34#ifndef __ASSEMBLY__
35
36#define MN10300_SRC_IOBCLK MN10300_IOBCLK
37
38#ifndef HZ
39# error HZ undeclared.
40#endif /* !HZ */
41
42#define MN10300_JCCLK (MN10300_SRC_IOBCLK)
43#define MN10300_TSCCLK (MN10300_SRC_IOBCLK)
44
45#define MN10300_JC_PER_HZ ((MN10300_JCCLK + HZ / 2) / HZ)
46#define MN10300_TSC_PER_HZ ((MN10300_TSCCLK + HZ / 2) / HZ)
47
48/* Check bit width of MTM interval value that sets base register */
49#if (MN10300_JC_PER_HZ - 1) > TMJCBR_MAX
50# error MTM tick timer interval value is overflow.
51#endif
52
53
54static inline void startup_jiffies_counter(void)
55{
56 u32 sync;
57
58 TMJCBR = MN10300_JC_PER_HZ - 1;
59 sync = TMJCBR;
60
61 TMJCMD = TMTMD_TMTLDE;
62 TMJCMD = TMTMD_TMTCNE;
63 sync = TMJCMD;
64
65 TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
66 sync = TMJCICR;
67}
68
69static inline void shutdown_jiffies_counter(void)
70{
71}
72
73#endif /* !__ASSEMBLY__ */
74
75
76/*
77 * timestamp counter specifications
78 */
79
80#define TMTSCBR_MAX 0xffffffff
81#define TMTSCMD TMSMD
82#define TMTSCBR TMSBR
83#define TMTSCBC TMSBC
84#define TMTSCICR TMSICR
85
86#ifndef __ASSEMBLY__
87
88static inline void startup_timestamp_counter(void)
89{
90 u32 sync;
91
92 /* set up TMS(Timestamp) 32bit timer register to count real time
93 * - count down from 4Gig-1 to 0 and wrap at IOBCLK rate
94 */
95
96 TMTSCBR = TMTSCBR_MAX;
97 sync = TMTSCBR;
98
99 TMTSCICR = 0;
100 sync = TMTSCICR;
101
102 TMTSCMD = TMTMD_TMTLDE;
103 TMTSCMD = TMTMD_TMTCNE;
104 sync = TMTSCMD;
105}
106
107static inline void shutdown_timestamp_counter(void)
108{
109 TMTSCMD = 0;
110}
111
112/*
113 * we use a cascaded pair of 16-bit down-counting timers to count I/O
114 * clock cycles for the purposes of time keeping
115 */
116typedef unsigned long cycles_t;
117
118static inline cycles_t read_timestamp_counter(void)
119{
120 return (cycles_t)TMTSCBC;
121}
122
123#endif /* !__ASSEMBLY__ */
124
125#endif /* _ASM_UNIT_TIMEX_H */
diff --git a/arch/mn10300/unit-asb2364/leds.c b/arch/mn10300/unit-asb2364/leds.c
new file mode 100644
index 000000000000..1ff830c372b3
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/leds.c
@@ -0,0 +1,98 @@
1/* leds.c: ASB2364 peripheral 7seg LEDs x4 support
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/init.h>
15
16#include <asm/io.h>
17#include <asm/processor.h>
18#include <asm/intctl-regs.h>
19#include <asm/rtc-regs.h>
20#include <unit/leds.h>
21
22#if MN10300_USE_7SEGLEDS
23static const u8 asb2364_led_hex_tbl[16] = {
24 0x80, 0xf2, 0x48, 0x60, 0x32, 0x24, 0x04, 0xf0,
25 0x00, 0x20, 0x10, 0x06, 0x8c, 0x42, 0x0c, 0x1c
26};
27
28static const u32 asb2364_led_chase_tbl[6] = {
29 ~0x02020202, /* top - segA */
30 ~0x04040404, /* right top - segB */
31 ~0x08080808, /* right bottom - segC */
32 ~0x10101010, /* bottom - segD */
33 ~0x20202020, /* left bottom - segE */
34 ~0x40404040, /* left top - segF */
35};
36
37static unsigned asb2364_led_chase;
38
39void peripheral_leds7x4_display_dec(unsigned int val, unsigned int points)
40{
41 u32 leds;
42
43 leds = asb2364_led_hex_tbl[(val/1000) % 10];
44 leds <<= 8;
45 leds |= asb2364_led_hex_tbl[(val/100) % 10];
46 leds <<= 8;
47 leds |= asb2364_led_hex_tbl[(val/10) % 10];
48 leds <<= 8;
49 leds |= asb2364_led_hex_tbl[val % 10];
50 leds |= points^0x01010101;
51
52 ASB2364_7SEGLEDS = leds;
53}
54
55void peripheral_leds7x4_display_hex(unsigned int val, unsigned int points)
56{
57 u32 leds;
58
59 leds = asb2364_led_hex_tbl[(val/1000) % 10];
60 leds <<= 8;
61 leds |= asb2364_led_hex_tbl[(val/100) % 10];
62 leds <<= 8;
63 leds |= asb2364_led_hex_tbl[(val/10) % 10];
64 leds <<= 8;
65 leds |= asb2364_led_hex_tbl[val % 10];
66 leds |= points^0x01010101;
67
68 ASB2364_7SEGLEDS = leds;
69}
70
71/* display triple horizontal bar and exception code */
72void peripheral_leds_display_exception(enum exception_code code)
73{
74 u32 leds;
75
76 leds = asb2364_led_hex_tbl[(code/0x100) % 0x10];
77 leds <<= 8;
78 leds |= asb2364_led_hex_tbl[(code/0x10) % 0x10];
79 leds <<= 8;
80 leds |= asb2364_led_hex_tbl[code % 0x10];
81 leds |= 0x6d010101;
82
83 ASB2364_7SEGLEDS = leds;
84}
85
86void peripheral_leds_led_chase(void)
87{
88 ASB2364_7SEGLEDS = asb2364_led_chase_tbl[asb2364_led_chase];
89 asb2364_led_chase++;
90 if (asb2364_led_chase >= 6)
91 asb2364_led_chase = 0;
92}
93#else /* MN10300_USE_7SEGLEDS */
94void peripheral_leds7x4_display_dec(unsigned int val, unsigned int points) { }
95void peripheral_leds7x4_display_hex(unsigned int val, unsigned int points) { }
96void peripheral_leds_display_exception(enum exception_code code) { }
97void peripheral_leds_led_chase(void) { }
98#endif /* MN10300_USE_7SEGLEDS */
diff --git a/arch/mn10300/unit-asb2364/unit-init.c b/arch/mn10300/unit-asb2364/unit-init.c
new file mode 100644
index 000000000000..a3fc09b43f84
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/unit-init.c
@@ -0,0 +1,85 @@
1/* ASB2364 initialisation
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/delay.h>
17
18#include <asm/io.h>
19#include <asm/setup.h>
20#include <asm/processor.h>
21#include <asm/irq.h>
22#include <asm/intctl-regs.h>
23
24/*
25 * initialise some of the unit hardware before gdbstub is set up
26 */
27asmlinkage void __init unit_init(void)
28{
29 /* set up the external interrupts */
30
31 /* XIRQ[0]: NAND RXBY */
32 /* SET_XIRQ_TRIGGER(0, XIRQ_TRIGGER_LOWLEVEL); */
33
34 /* XIRQ[1]: LAN, UART, I2C, USB, PCI, FPGA */
35 SET_XIRQ_TRIGGER(1, XIRQ_TRIGGER_LOWLEVEL);
36
37 /* XIRQ[2]: Extend Slot 1-9 */
38 /* SET_XIRQ_TRIGGER(2, XIRQ_TRIGGER_LOWLEVEL); */
39
40#if defined(CONFIG_EXT_SERIAL_IRQ_LEVEL) && \
41 defined(CONFIG_ETHERNET_IRQ_LEVEL) && \
42 (CONFIG_EXT_SERIAL_IRQ_LEVEL != CONFIG_ETHERNET_IRQ_LEVEL)
43# error CONFIG_EXT_SERIAL_IRQ_LEVEL != CONFIG_ETHERNET_IRQ_LEVEL
44#endif
45
46#if defined(CONFIG_EXT_SERIAL_IRQ_LEVEL)
47 set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_EXT_SERIAL_IRQ_LEVEL));
48#elif defined(CONFIG_ETHERNET_IRQ_LEVEL)
49 set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_ETHERNET_IRQ_LEVEL));
50#endif
51}
52
53/*
54 * initialise the rest of the unit hardware after gdbstub is ready
55 */
56asmlinkage void __init unit_setup(void)
57{
58
59}
60
61/*
62 * initialise the external interrupts used by a unit of this type
63 */
64void __init unit_init_IRQ(void)
65{
66 unsigned int extnum;
67
68 for (extnum = 0 ; extnum < NR_XIRQS ; extnum++) {
69 switch (GET_XIRQ_TRIGGER(extnum)) {
70 /* LEVEL triggered interrupts should be made
71 * post-ACK'able as they hold their lines until
72 * serviced
73 */
74 case XIRQ_TRIGGER_HILEVEL:
75 case XIRQ_TRIGGER_LOWLEVEL:
76 mn10300_set_lateack_irq_type(XIRQ2IRQ(extnum));
77 break;
78 default:
79 break;
80 }
81 }
82
83#define IRQCTL __SYSREG(0xd5000090, u32)
84 IRQCTL |= 0x02;
85}