aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile3
-rw-r--r--arch/sh/kernel/cpu/init.c41
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c19
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S12
-rw-r--r--arch/sh/kernel/cpu/sh2/probe.c32
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c62
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c16
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c89
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S207
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c42
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7709.c21
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c183
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c4
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c66
-rw-r--r--arch/sh/kernel/debugtraps.S41
-rw-r--r--arch/sh/kernel/early_printk.c24
-rw-r--r--arch/sh/kernel/entry-common.S119
-rw-r--r--arch/sh/kernel/io_generic.c12
-rw-r--r--arch/sh/kernel/kgdb_stub.c7
-rw-r--r--arch/sh/kernel/process.c95
-rw-r--r--arch/sh/kernel/setup.c49
-rw-r--r--arch/sh/kernel/sh_ksyms.c1
-rw-r--r--arch/sh/kernel/signal.c6
-rw-r--r--arch/sh/kernel/syscalls.S8
-rw-r--r--arch/sh/kernel/traps.c4
25 files changed, 557 insertions, 606 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 2f6d2bcb1c93..ff30d7f58043 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -6,7 +6,8 @@ extra-y := head.o init_task.o vmlinux.lds
6 6
7obj-y := process.o signal.o traps.o irq.o \ 7obj-y := process.o signal.o traps.o irq.o \
8 ptrace.o setup.o time.o sys_sh.o semaphore.o \ 8 ptrace.o setup.o time.o sys_sh.o semaphore.o \
9 io.o io_generic.o sh_ksyms.o syscalls.o 9 io.o io_generic.o sh_ksyms.o syscalls.o \
10 debugtraps.o
10 11
11obj-y += cpu/ timers/ 12obj-y += cpu/ timers/
12obj-$(CONFIG_VSYSCALL) += vsyscall/ 13obj-$(CONFIG_VSYSCALL) += vsyscall/
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 48121766e8d2..4b339a640b13 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * CPU init code 4 * CPU init code
5 * 5 *
6 * Copyright (C) 2002, 2003 Paul Mundt 6 * Copyright (C) 2002 - 2006 Paul Mundt
7 * Copyright (C) 2003 Richard Curnow 7 * Copyright (C) 2003 Richard Curnow
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
@@ -12,6 +12,8 @@
12 */ 12 */
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/mm.h>
16#include <asm/mmu_context.h>
15#include <asm/processor.h> 17#include <asm/processor.h>
16#include <asm/uaccess.h> 18#include <asm/uaccess.h>
17#include <asm/page.h> 19#include <asm/page.h>
@@ -46,7 +48,7 @@ static void __init cache_init(void)
46{ 48{
47 unsigned long ccr, flags; 49 unsigned long ccr, flags;
48 50
49 if (cpu_data->type == CPU_SH_NONE) 51 if (current_cpu_data.type == CPU_SH_NONE)
50 panic("Unknown CPU"); 52 panic("Unknown CPU");
51 53
52 jump_to_P2(); 54 jump_to_P2();
@@ -66,7 +68,7 @@ static void __init cache_init(void)
66 if (ccr & CCR_CACHE_ENABLE) { 68 if (ccr & CCR_CACHE_ENABLE) {
67 unsigned long ways, waysize, addrstart; 69 unsigned long ways, waysize, addrstart;
68 70
69 waysize = cpu_data->dcache.sets; 71 waysize = current_cpu_data.dcache.sets;
70 72
71#ifdef CCR_CACHE_ORA 73#ifdef CCR_CACHE_ORA
72 /* 74 /*
@@ -77,7 +79,7 @@ static void __init cache_init(void)
77 waysize >>= 1; 79 waysize >>= 1;
78#endif 80#endif
79 81
80 waysize <<= cpu_data->dcache.entry_shift; 82 waysize <<= current_cpu_data.dcache.entry_shift;
81 83
82#ifdef CCR_CACHE_EMODE 84#ifdef CCR_CACHE_EMODE
83 /* If EMODE is not set, we only have 1 way to flush. */ 85 /* If EMODE is not set, we only have 1 way to flush. */
@@ -85,7 +87,7 @@ static void __init cache_init(void)
85 ways = 1; 87 ways = 1;
86 else 88 else
87#endif 89#endif
88 ways = cpu_data->dcache.ways; 90 ways = current_cpu_data.dcache.ways;
89 91
90 addrstart = CACHE_OC_ADDRESS_ARRAY; 92 addrstart = CACHE_OC_ADDRESS_ARRAY;
91 do { 93 do {
@@ -93,10 +95,10 @@ static void __init cache_init(void)
93 95
94 for (addr = addrstart; 96 for (addr = addrstart;
95 addr < addrstart + waysize; 97 addr < addrstart + waysize;
96 addr += cpu_data->dcache.linesz) 98 addr += current_cpu_data.dcache.linesz)
97 ctrl_outl(0, addr); 99 ctrl_outl(0, addr);
98 100
99 addrstart += cpu_data->dcache.way_incr; 101 addrstart += current_cpu_data.dcache.way_incr;
100 } while (--ways); 102 } while (--ways);
101 } 103 }
102 104
@@ -108,7 +110,7 @@ static void __init cache_init(void)
108 110
109#ifdef CCR_CACHE_EMODE 111#ifdef CCR_CACHE_EMODE
110 /* Force EMODE if possible */ 112 /* Force EMODE if possible */
111 if (cpu_data->dcache.ways > 1) 113 if (current_cpu_data.dcache.ways > 1)
112 flags |= CCR_CACHE_EMODE; 114 flags |= CCR_CACHE_EMODE;
113 else 115 else
114 flags &= ~CCR_CACHE_EMODE; 116 flags &= ~CCR_CACHE_EMODE;
@@ -125,10 +127,10 @@ static void __init cache_init(void)
125#ifdef CONFIG_SH_OCRAM 127#ifdef CONFIG_SH_OCRAM
126 /* Turn on OCRAM -- halve the OC */ 128 /* Turn on OCRAM -- halve the OC */
127 flags |= CCR_CACHE_ORA; 129 flags |= CCR_CACHE_ORA;
128 cpu_data->dcache.sets >>= 1; 130 current_cpu_data.dcache.sets >>= 1;
129 131
130 cpu_data->dcache.way_size = cpu_data->dcache.sets * 132 current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
131 cpu_data->dcache.linesz; 133 current_cpu_data.dcache.linesz;
132#endif 134#endif
133 135
134 ctrl_outl(flags, CCR); 136 ctrl_outl(flags, CCR);
@@ -170,7 +172,7 @@ static void __init dsp_init(void)
170 172
171 /* If the DSP bit is still set, this CPU has a DSP */ 173 /* If the DSP bit is still set, this CPU has a DSP */
172 if (sr & SR_DSP) 174 if (sr & SR_DSP)
173 cpu_data->flags |= CPU_HAS_DSP; 175 current_cpu_data.flags |= CPU_HAS_DSP;
174 176
175 /* Now that we've determined the DSP status, clear the DSP bit. */ 177 /* Now that we've determined the DSP status, clear the DSP bit. */
176 release_dsp(); 178 release_dsp();
@@ -202,22 +204,28 @@ asmlinkage void __init sh_cpu_init(void)
202 cache_init(); 204 cache_init();
203 205
204 shm_align_mask = max_t(unsigned long, 206 shm_align_mask = max_t(unsigned long,
205 cpu_data->dcache.way_size - 1, 207 current_cpu_data.dcache.way_size - 1,
206 PAGE_SIZE - 1); 208 PAGE_SIZE - 1);
207 209
208 /* Disable the FPU */ 210 /* Disable the FPU */
209 if (fpu_disabled) { 211 if (fpu_disabled) {
210 printk("FPU Disabled\n"); 212 printk("FPU Disabled\n");
211 cpu_data->flags &= ~CPU_HAS_FPU; 213 current_cpu_data.flags &= ~CPU_HAS_FPU;
212 disable_fpu(); 214 disable_fpu();
213 } 215 }
214 216
215 /* FPU initialization */ 217 /* FPU initialization */
216 if ((cpu_data->flags & CPU_HAS_FPU)) { 218 if ((current_cpu_data.flags & CPU_HAS_FPU)) {
217 clear_thread_flag(TIF_USEDFPU); 219 clear_thread_flag(TIF_USEDFPU);
218 clear_used_math(); 220 clear_used_math();
219 } 221 }
220 222
223 /*
224 * Initialize the per-CPU ASID cache very early, since the
225 * TLB flushing routines depend on this being setup.
226 */
227 current_cpu_data.asid_cache = NO_CONTEXT;
228
221#ifdef CONFIG_SH_DSP 229#ifdef CONFIG_SH_DSP
222 /* Probe for DSP */ 230 /* Probe for DSP */
223 dsp_init(); 231 dsp_init();
@@ -225,7 +233,7 @@ asmlinkage void __init sh_cpu_init(void)
225 /* Disable the DSP */ 233 /* Disable the DSP */
226 if (dsp_disabled) { 234 if (dsp_disabled) {
227 printk("DSP Disabled\n"); 235 printk("DSP Disabled\n");
228 cpu_data->flags &= ~CPU_HAS_DSP; 236 current_cpu_data.flags &= ~CPU_HAS_DSP;
229 release_dsp(); 237 release_dsp();
230 } 238 }
231#endif 239#endif
@@ -240,4 +248,3 @@ asmlinkage void __init sh_cpu_init(void)
240 ubc_wakeup(); 248 ubc_wakeup();
241#endif 249#endif
242} 250}
243
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 35eb5751a3aa..210280b6fddf 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -43,16 +43,29 @@ static struct irq_chip ipr_irq_chip = {
43 .mask_ack = disable_ipr_irq, 43 .mask_ack = disable_ipr_irq,
44}; 44};
45 45
46unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak));
47unsigned int map_ipridx_to_addr(int idx)
48{
49 return 0;
50}
51
46void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) 52void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
47{ 53{
48 int i; 54 int i;
49 55
50 for (i = 0; i < nr_irqs; i++) { 56 for (i = 0; i < nr_irqs; i++) {
51 unsigned int irq = table[i].irq; 57 unsigned int irq = table[i].irq;
52 table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); 58
59 if (!irq)
60 irq = table[i].irq = i;
61
53 /* could the IPR index be mapped, if not we ignore this */ 62 /* could the IPR index be mapped, if not we ignore this */
54 if (table[i].addr == 0) 63 if (!table[i].addr) {
55 continue; 64 table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
65 if (!table[i].addr)
66 continue;
67 }
68
56 disable_irq_nosync(irq); 69 disable_irq_nosync(irq);
57 set_irq_chip_and_handler_name(irq, &ipr_irq_chip, 70 set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
58 handle_level_irq, "level"); 71 handle_level_irq, "level");
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index d51fa5e9904a..7f7d292f36ec 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -178,12 +178,10 @@ interrupt_entry:
1788: .long do_exception_error 1788: .long do_exception_error
179 179
180trap_entry: 180trap_entry:
181 /* verbose BUG trapa entry check */ 181 mov #0x30,r8
182 mov #0x3e,r8 182 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
183 cmp/ge r8,r9 183 bt 1f
184 bf/s 1f 184 add #-0x10,r9 ! convert SH2 to SH3/4 ABI
185 add #-0x10,r9
186 add #0x10,r9
1871: 1851:
188 shll2 r9 ! TRA 186 shll2 r9 ! TRA
189 mov #OFF_TRA,r8 187 mov #OFF_TRA,r8
@@ -206,7 +204,7 @@ trap_entry:
206 204
207#if defined(CONFIG_SH_STANDARD_BIOS) 205#if defined(CONFIG_SH_STANDARD_BIOS)
208 /* Unwind the stack and jmp to the debug entry */ 206 /* Unwind the stack and jmp to the debug entry */
209debug_kernel_fw: 207ENTRY(sh_bios_handler)
210 mov r15,r0 208 mov r15,r0
211 add #(22-4)*4-4,r0 209 add #(22-4)*4-4,r0
212 ldc.l @r0+,gbr 210 ldc.l @r0+,gbr
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
index ba527d9b5024..108e81b682ed 100644
--- a/arch/sh/kernel/cpu/sh2/probe.c
+++ b/arch/sh/kernel/cpu/sh2/probe.c
@@ -18,27 +18,27 @@
18int __init detect_cpu_and_cache_system(void) 18int __init detect_cpu_and_cache_system(void)
19{ 19{
20#if defined(CONFIG_CPU_SUBTYPE_SH7604) 20#if defined(CONFIG_CPU_SUBTYPE_SH7604)
21 cpu_data->type = CPU_SH7604; 21 current_cpu_data.type = CPU_SH7604;
22 cpu_data->dcache.ways = 4; 22 current_cpu_data.dcache.ways = 4;
23 cpu_data->dcache.way_incr = (1<<10); 23 current_cpu_data.dcache.way_incr = (1<<10);
24 cpu_data->dcache.sets = 64; 24 current_cpu_data.dcache.sets = 64;
25 cpu_data->dcache.entry_shift = 4; 25 current_cpu_data.dcache.entry_shift = 4;
26 cpu_data->dcache.linesz = L1_CACHE_BYTES; 26 current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
27 cpu_data->dcache.flags = 0; 27 current_cpu_data.dcache.flags = 0;
28#elif defined(CONFIG_CPU_SUBTYPE_SH7619) 28#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
29 cpu_data->type = CPU_SH7619; 29 current_cpu_data.type = CPU_SH7619;
30 cpu_data->dcache.ways = 4; 30 current_cpu_data.dcache.ways = 4;
31 cpu_data->dcache.way_incr = (1<<12); 31 current_cpu_data.dcache.way_incr = (1<<12);
32 cpu_data->dcache.sets = 256; 32 current_cpu_data.dcache.sets = 256;
33 cpu_data->dcache.entry_shift = 4; 33 current_cpu_data.dcache.entry_shift = 4;
34 cpu_data->dcache.linesz = L1_CACHE_BYTES; 34 current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
35 cpu_data->dcache.flags = 0; 35 current_cpu_data.dcache.flags = 0;
36#endif 36#endif
37 /* 37 /*
38 * SH-2 doesn't have separate caches 38 * SH-2 doesn't have separate caches
39 */ 39 */
40 cpu_data->dcache.flags |= SH_CACHE_COMBINED; 40 current_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
41 cpu_data->icache = cpu_data->dcache; 41 current_cpu_data.icache = current_cpu_data.dcache;
42 42
43 return 0; 43 return 0;
44} 44}
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index 79283e6c1d8f..f83ff8a68f35 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -52,42 +52,38 @@ static int __init sh7619_devices_setup(void)
52} 52}
53__initcall(sh7619_devices_setup); 53__initcall(sh7619_devices_setup);
54 54
55#define INTC_IPRC 0xf8080000UL
56#define INTC_IPRD 0xf8080002UL
57
58#define CMI0_IRQ 86
59
60#define SCIF0_ERI_IRQ 88
61#define SCIF0_RXI_IRQ 89
62#define SCIF0_BRI_IRQ 90
63#define SCIF0_TXI_IRQ 91
64
65#define SCIF1_ERI_IRQ 92
66#define SCIF1_RXI_IRQ 93
67#define SCIF1_BRI_IRQ 94
68#define SCIF1_TXI_IRQ 95
69
70#define SCIF2_BRI_IRQ 96
71#define SCIF2_ERI_IRQ 97
72#define SCIF2_RXI_IRQ 98
73#define SCIF2_TXI_IRQ 99
74
75static struct ipr_data sh7619_ipr_map[] = { 55static struct ipr_data sh7619_ipr_map[] = {
76 { CMI0_IRQ, INTC_IPRC, 1, 2 }, 56 { 86, 0, 4, 2 }, /* CMI0 */
77 { SCIF0_ERI_IRQ, INTC_IPRD, 3, 3 }, 57 { 88, 1, 12, 3 }, /* SCIF0_ERI */
78 { SCIF0_RXI_IRQ, INTC_IPRD, 3, 3 }, 58 { 89, 1, 12, 3 }, /* SCIF0_RXI */
79 { SCIF0_BRI_IRQ, INTC_IPRD, 3, 3 }, 59 { 90, 1, 12, 3 }, /* SCIF0_BRI */
80 { SCIF0_TXI_IRQ, INTC_IPRD, 3, 3 }, 60 { 91, 1, 12, 3 }, /* SCIF0_TXI */
81 { SCIF1_ERI_IRQ, INTC_IPRD, 2, 3 }, 61 { 92, 1, 8, 3 }, /* SCIF1_ERI */
82 { SCIF1_RXI_IRQ, INTC_IPRD, 2, 3 }, 62 { 93, 1, 8, 3 }, /* SCIF1_RXI */
83 { SCIF1_BRI_IRQ, INTC_IPRD, 2, 3 }, 63 { 94, 1, 8, 3 }, /* SCIF1_BRI */
84 { SCIF1_TXI_IRQ, INTC_IPRD, 2, 3 }, 64 { 95, 1, 8, 3 }, /* SCIF1_TXI */
85 { SCIF2_ERI_IRQ, INTC_IPRD, 1, 3 }, 65 { 96, 1, 4, 3 }, /* SCIF2_ERI */
86 { SCIF2_RXI_IRQ, INTC_IPRD, 1, 3 }, 66 { 97, 1, 4, 3 }, /* SCIF2_RXI */
87 { SCIF2_BRI_IRQ, INTC_IPRD, 1, 3 }, 67 { 98, 1, 4, 3 }, /* SCIF2_BRI */
88 { SCIF2_TXI_IRQ, INTC_IPRD, 1, 3 }, 68 { 99, 1, 4, 3 }, /* SCIF2_TXI */
89}; 69};
90 70
71static unsigned int ipr_offsets[] = {
72 0xf8080000, /* IPRC */
73 0xf8080002, /* IPRD */
74 0xf8080004, /* IPRE */
75 0xf8080006, /* IPRF */
76 0xf8080008, /* IPRG */
77};
78
79/* given the IPR index return the address of the IPR register */
80unsigned int map_ipridx_to_addr(int idx)
81{
82 if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
83 return 0;
84 return ipr_offsets[idx];
85}
86
91void __init init_IRQ_ipr(void) 87void __init init_IRQ_ipr(void)
92{ 88{
93 make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); 89 make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map));
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index 87c6c0542089..426f6db01fc6 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -17,14 +17,14 @@
17int __init detect_cpu_and_cache_system(void) 17int __init detect_cpu_and_cache_system(void)
18{ 18{
19 /* Just SH7206 for now .. */ 19 /* Just SH7206 for now .. */
20 cpu_data->type = CPU_SH7206; 20 current_cpu_data.type = CPU_SH7206;
21 21
22 cpu_data->dcache.ways = 4; 22 current_cpu_data.dcache.ways = 4;
23 cpu_data->dcache.way_incr = (1 << 11); 23 current_cpu_data.dcache.way_incr = (1 << 11);
24 cpu_data->dcache.sets = 128; 24 current_cpu_data.dcache.sets = 128;
25 cpu_data->dcache.entry_shift = 4; 25 current_cpu_data.dcache.entry_shift = 4;
26 cpu_data->dcache.linesz = L1_CACHE_BYTES; 26 current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
27 cpu_data->dcache.flags = 0; 27 current_cpu_data.dcache.flags = 0;
28 28
29 /* 29 /*
30 * The icache is the same as the dcache as far as this setup is 30 * The icache is the same as the dcache as far as this setup is
@@ -32,7 +32,7 @@ int __init detect_cpu_and_cache_system(void)
32 * lacks the U bit that the dcache has, none of this has any bearing 32 * lacks the U bit that the dcache has, none of this has any bearing
33 * on the cache info. 33 * on the cache info.
34 */ 34 */
35 cpu_data->icache = cpu_data->dcache; 35 current_cpu_data.icache = current_cpu_data.dcache;
36 36
37 return 0; 37 return 0;
38} 38}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 4b60fcc7d667..4ed9110632bc 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -57,55 +57,52 @@ static int __init sh7206_devices_setup(void)
57} 57}
58__initcall(sh7206_devices_setup); 58__initcall(sh7206_devices_setup);
59 59
60#define INTC_IPR08 0xfffe0c04UL
61#define INTC_IPR09 0xfffe0c06UL
62#define INTC_IPR14 0xfffe0c10UL
63
64#define CMI0_IRQ 140
65
66#define MTU1_TGI1A 164
67
68#define SCIF0_BRI_IRQ 240
69#define SCIF0_ERI_IRQ 241
70#define SCIF0_RXI_IRQ 242
71#define SCIF0_TXI_IRQ 243
72
73#define SCIF1_BRI_IRQ 244
74#define SCIF1_ERI_IRQ 245
75#define SCIF1_RXI_IRQ 246
76#define SCIF1_TXI_IRQ 247
77
78#define SCIF2_BRI_IRQ 248
79#define SCIF2_ERI_IRQ 249
80#define SCIF2_RXI_IRQ 250
81#define SCIF2_TXI_IRQ 251
82
83#define SCIF3_BRI_IRQ 252
84#define SCIF3_ERI_IRQ 253
85#define SCIF3_RXI_IRQ 254
86#define SCIF3_TXI_IRQ 255
87
88static struct ipr_data sh7206_ipr_map[] = { 60static struct ipr_data sh7206_ipr_map[] = {
89 { CMI0_IRQ, INTC_IPR08, 3, 2 }, 61 { 140, 7, 12, 2 }, /* CMI0 */
90 { MTU2_TGI1A, INTC_IPR09, 1, 2 }, 62 { 164, 8, 4, 2 }, /* MTU2_TGI1A */
91 { SCIF0_ERI_IRQ, INTC_IPR14, 3, 3 }, 63 { 240, 13, 12, 3 }, /* SCIF0_BRI */
92 { SCIF0_RXI_IRQ, INTC_IPR14, 3, 3 }, 64 { 241, 13, 12, 3 }, /* SCIF0_ERI */
93 { SCIF0_BRI_IRQ, INTC_IPR14, 3, 3 }, 65 { 242, 13, 12, 3 }, /* SCIF0_RXI */
94 { SCIF0_TXI_IRQ, INTC_IPR14, 3, 3 }, 66 { 243, 13, 12, 3 }, /* SCIF0_TXI */
95 { SCIF1_ERI_IRQ, INTC_IPR14, 2, 3 }, 67 { 244, 13, 8, 3 }, /* SCIF1_BRI */
96 { SCIF1_RXI_IRQ, INTC_IPR14, 2, 3 }, 68 { 245, 13, 8, 3 }, /* SCIF1_ERI */
97 { SCIF1_BRI_IRQ, INTC_IPR14, 2, 3 }, 69 { 246, 13, 8, 3 }, /* SCIF1_RXI */
98 { SCIF1_TXI_IRQ, INTC_IPR14, 2, 3 }, 70 { 247, 13, 8, 3 }, /* SCIF1_TXI */
99 { SCIF2_ERI_IRQ, INTC_IPR14, 1, 3 }, 71 { 248, 13, 4, 3 }, /* SCIF2_BRI */
100 { SCIF2_RXI_IRQ, INTC_IPR14, 1, 3 }, 72 { 249, 13, 4, 3 }, /* SCIF2_ERI */
101 { SCIF2_BRI_IRQ, INTC_IPR14, 1, 3 }, 73 { 250, 13, 4, 3 }, /* SCIF2_RXI */
102 { SCIF2_TXI_IRQ, INTC_IPR14, 1, 3 }, 74 { 251, 13, 4, 3 }, /* SCIF2_TXI */
103 { SCIF3_ERI_IRQ, INTC_IPR14, 0, 3 }, 75 { 252, 13, 0, 3 }, /* SCIF3_BRI */
104 { SCIF3_RXI_IRQ, INTC_IPR14, 0, 3 }, 76 { 253, 13, 0, 3 }, /* SCIF3_ERI */
105 { SCIF3_BRI_IRQ, INTC_IPR14, 0, 3 }, 77 { 254, 13, 0, 3 }, /* SCIF3_RXI */
106 { SCIF3_TXI_IRQ, INTC_IPR14, 0, 3 }, 78 { 255, 13, 0, 3 }, /* SCIF3_TXI */
79};
80
81static unsigned int ipr_offsets[] = {
82 0xfffe0818, /* IPR01 */
83 0xfffe081a, /* IPR02 */
84 0, /* unused */
85 0, /* unused */
86 0xfffe0820, /* IPR05 */
87 0xfffe0c00, /* IPR06 */
88 0xfffe0c02, /* IPR07 */
89 0xfffe0c04, /* IPR08 */
90 0xfffe0c06, /* IPR09 */
91 0xfffe0c08, /* IPR10 */
92 0xfffe0c0a, /* IPR11 */
93 0xfffe0c0c, /* IPR12 */
94 0xfffe0c0e, /* IPR13 */
95 0xfffe0c10, /* IPR14 */
107}; 96};
108 97
98/* given the IPR index return the address of the IPR register */
99unsigned int map_ipridx_to_addr(int idx)
100{
101 if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
102 return 0;
103 return ipr_offsets[idx];
104}
105
109void __init init_IRQ_ipr(void) 106void __init init_IRQ_ipr(void)
110{ 107{
111 make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); 108 make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map));
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 8c0dc2700c69..c19205b0f2c0 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -13,10 +13,8 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/asm-offsets.h> 14#include <asm/asm-offsets.h>
15#include <asm/thread_info.h> 15#include <asm/thread_info.h>
16#include <asm/unistd.h>
17#include <asm/cpu/mmu_context.h> 16#include <asm/cpu/mmu_context.h>
18#include <asm/pgtable.h> 17#include <asm/unistd.h>
19#include <asm/page.h>
20 18
21! NOTE: 19! NOTE:
22! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address 20! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
@@ -138,14 +136,29 @@ ENTRY(tlb_protection_violation_store)
138 136
139call_dpf: 137call_dpf:
140 mov.l 1f, r0 138 mov.l 1f, r0
141 mov.l @r0, r6 ! address 139 mov r5, r8
140 mov.l @r0, r6
141 mov r6, r9
142 mov.l 2f, r0
143 sts pr, r10
144 jsr @r0
145 mov r15, r4
146 !
147 tst r0, r0
148 bf/s 0f
149 lds r10, pr
150 rts
151 nop
1520: sti
142 mov.l 3f, r0 153 mov.l 3f, r0
143 154 mov r9, r6
155 mov r8, r5
144 jmp @r0 156 jmp @r0
145 mov r15, r4 ! regs 157 mov r15, r4
146 158
147 .align 2 159 .align 2
1481: .long MMU_TEA 1601: .long MMU_TEA
1612: .long __do_page_fault
1493: .long do_page_fault 1623: .long do_page_fault
150 163
151 .align 2 164 .align 2
@@ -173,7 +186,7 @@ call_dae:
173 186
174#if defined(CONFIG_SH_STANDARD_BIOS) 187#if defined(CONFIG_SH_STANDARD_BIOS)
175 /* Unwind the stack and jmp to the debug entry */ 188 /* Unwind the stack and jmp to the debug entry */
176debug_kernel_fw: 189ENTRY(sh_bios_handler)
177 mov.l @r15+, r0 190 mov.l @r15+, r0
178 mov.l @r15+, r1 191 mov.l @r15+, r1
179 mov.l @r15+, r2 192 mov.l @r15+, r2
@@ -332,175 +345,9 @@ general_exception:
332! 345!
333! 346!
334 347
335/* This code makes some assumptions to improve performance.
336 * Make sure they are stil true. */
337#if PTRS_PER_PGD != PTRS_PER_PTE
338#error PGD and PTE sizes don't match
339#endif
340
341/* gas doesn't flag impossible values for mov #immediate as an error */
342#if (_PAGE_PRESENT >> 2) > 0x7f
343#error cannot load PAGE_PRESENT as an immediate
344#endif
345#if _PAGE_DIRTY > 0x7f
346#error cannot load PAGE_DIRTY as an immediate
347#endif
348#if (_PAGE_PRESENT << 2) != _PAGE_ACCESSED
349#error cannot derive PAGE_ACCESSED from PAGE_PRESENT
350#endif
351
352#if defined(CONFIG_CPU_SH4)
353#define ldmmupteh(r) mov.l 8f, r
354#else
355#define ldmmupteh(r) mov #MMU_PTEH, r
356#endif
357
358 .balign 1024,0,1024 348 .balign 1024,0,1024
359tlb_miss: 349tlb_miss:
360#ifdef COUNT_EXCEPTIONS 350 mov.l 1f, k2
361 ! Increment the counts
362 mov.l 9f, k1
363 mov.l @k1, k2
364 add #1, k2
365 mov.l k2, @k1
366#endif
367
368 ! k0 scratch
369 ! k1 pgd and pte pointers
370 ! k2 faulting address
371 ! k3 pgd and pte index masks
372 ! k4 shift
373
374 ! Load up the pgd entry (k1)
375
376 ldmmupteh(k0) ! 9 LS (latency=2) MMU_PTEH
377
378 mov.w 4f, k3 ! 8 LS (latency=2) (PTRS_PER_PGD-1) << 2
379 mov #-(PGDIR_SHIFT-2), k4 ! 6 EX
380
381 mov.l @(MMU_TEA-MMU_PTEH,k0), k2 ! 18 LS (latency=2)
382
383 mov.l @(MMU_TTB-MMU_PTEH,k0), k1 ! 18 LS (latency=2)
384
385 mov k2, k0 ! 5 MT (latency=0)
386 shld k4, k0 ! 99 EX
387
388 and k3, k0 ! 78 EX
389
390 mov.l @(k0, k1), k1 ! 21 LS (latency=2)
391 mov #-(PAGE_SHIFT-2), k4 ! 6 EX
392
393 ! Load up the pte entry (k2)
394
395 mov k2, k0 ! 5 MT (latency=0)
396 shld k4, k0 ! 99 EX
397
398 tst k1, k1 ! 86 MT
399
400 bt 20f ! 110 BR
401
402 and k3, k0 ! 78 EX
403 mov.w 5f, k4 ! 8 LS (latency=2) _PAGE_PRESENT
404
405 mov.l @(k0, k1), k2 ! 21 LS (latency=2)
406 add k0, k1 ! 49 EX
407
408#ifdef CONFIG_CPU_HAS_PTEA
409 ! Test the entry for present and _PAGE_ACCESSED
410
411 mov #-28, k3 ! 6 EX
412 mov k2, k0 ! 5 MT (latency=0)
413
414 tst k4, k2 ! 68 MT
415 shld k3, k0 ! 99 EX
416
417 bt 20f ! 110 BR
418
419 ! Set PTEA register
420 ! MMU_PTEA = ((pteval >> 28) & 0xe) | (pteval & 0x1)
421 !
422 ! k0=pte>>28, k1=pte*, k2=pte, k3=<unused>, k4=_PAGE_PRESENT
423
424 and #0xe, k0 ! 79 EX
425
426 mov k0, k3 ! 5 MT (latency=0)
427 mov k2, k0 ! 5 MT (latency=0)
428
429 and #1, k0 ! 79 EX
430
431 or k0, k3 ! 82 EX
432
433 ldmmupteh(k0) ! 9 LS (latency=2)
434 shll2 k4 ! 101 EX _PAGE_ACCESSED
435
436 tst k4, k2 ! 68 MT
437
438 mov.l k3, @(MMU_PTEA-MMU_PTEH,k0) ! 27 LS
439
440 mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
441
442 ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
443#else
444
445 ! Test the entry for present and _PAGE_ACCESSED
446
447 mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
448 tst k4, k2 ! 68 MT
449
450 shll2 k4 ! 101 EX _PAGE_ACCESSED
451 ldmmupteh(k0) ! 9 LS (latency=2)
452
453 bt 20f ! 110 BR
454 tst k4, k2 ! 68 MT
455
456 ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
457
458#endif
459
460 ! Set up the entry
461
462 and k2, k3 ! 78 EX
463 bt/s 10f ! 108 BR
464
465 mov.l k3, @(MMU_PTEL-MMU_PTEH,k0) ! 27 LS
466
467 ldtlb ! 128 CO
468
469 ! At least one instruction between ldtlb and rte
470 nop ! 119 NOP
471
472 rte ! 126 CO
473
474 nop ! 119 NOP
475
476
47710: or k4, k2 ! 82 EX
478
479 ldtlb ! 128 CO
480
481 ! At least one instruction between ldtlb and rte
482 mov.l k2, @k1 ! 27 LS
483
484 rte ! 126 CO
485
486 ! Note we cannot execute mov here, because it is executed after
487 ! restoring SSR, so would be executed in user space.
488 nop ! 119 NOP
489
490
491 .align 5
492 ! Once cache line if possible...
4931: .long swapper_pg_dir
4944: .short (PTRS_PER_PGD-1) << 2
4955: .short _PAGE_PRESENT
4967: .long _PAGE_FLAGS_HARDWARE_MASK
4978: .long MMU_PTEH
498#ifdef COUNT_EXCEPTIONS
4999: .long exception_count_miss
500#endif
501
502 ! Either pgd or pte not present
50320: mov.l 1f, k2
504 mov.l 4f, k3 351 mov.l 4f, k3
505 bra handle_exception 352 bra handle_exception
506 mov.l @k2, k2 353 mov.l @k2, k2
@@ -651,15 +498,6 @@ skip_save:
651 bf interrupt_exception 498 bf interrupt_exception
652 shlr2 r8 499 shlr2 r8
653 shlr r8 500 shlr r8
654
655#ifdef COUNT_EXCEPTIONS
656 mov.l 5f, r9
657 add r8, r9
658 mov.l @r9, r10
659 add #1, r10
660 mov.l r10, @r9
661#endif
662
663 mov.l 4f, r9 501 mov.l 4f, r9
664 add r8, r9 502 add r8, r9
665 mov.l @r9, r9 503 mov.l @r9, r9
@@ -673,9 +511,6 @@ skip_save:
6732: .long 0x000080f0 ! FD=1, IMASK=15 5112: .long 0x000080f0 ! FD=1, IMASK=15
6743: .long 0xcfffffff ! RB=0, BL=0 5123: .long 0xcfffffff ! RB=0, BL=0
6754: .long exception_handling_table 5134: .long exception_handling_table
676#ifdef COUNT_EXCEPTIONS
6775: .long exception_count_table
678#endif
679 514
680interrupt_exception: 515interrupt_exception:
681 mov.l 1f, r9 516 mov.l 1f, r9
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index e67098836290..821b0ab7b528 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -50,41 +50,41 @@ int __init detect_cpu_and_cache_system(void)
50 50
51 back_to_P1(); 51 back_to_P1();
52 52
53 cpu_data->dcache.ways = 4; 53 current_cpu_data.dcache.ways = 4;
54 cpu_data->dcache.entry_shift = 4; 54 current_cpu_data.dcache.entry_shift = 4;
55 cpu_data->dcache.linesz = L1_CACHE_BYTES; 55 current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
56 cpu_data->dcache.flags = 0; 56 current_cpu_data.dcache.flags = 0;
57 57
58 /* 58 /*
59 * 7709A/7729 has 16K cache (256-entry), while 7702 has only 59 * 7709A/7729 has 16K cache (256-entry), while 7702 has only
60 * 2K(direct) 7702 is not supported (yet) 60 * 2K(direct) 7702 is not supported (yet)
61 */ 61 */
62 if (data0 == data1 && data2 == data3) { /* Shadow */ 62 if (data0 == data1 && data2 == data3) { /* Shadow */
63 cpu_data->dcache.way_incr = (1 << 11); 63 current_cpu_data.dcache.way_incr = (1 << 11);
64 cpu_data->dcache.entry_mask = 0x7f0; 64 current_cpu_data.dcache.entry_mask = 0x7f0;
65 cpu_data->dcache.sets = 128; 65 current_cpu_data.dcache.sets = 128;
66 cpu_data->type = CPU_SH7708; 66 current_cpu_data.type = CPU_SH7708;
67 67
68 cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC; 68 current_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC;
69 } else { /* 7709A or 7729 */ 69 } else { /* 7709A or 7729 */
70 cpu_data->dcache.way_incr = (1 << 12); 70 current_cpu_data.dcache.way_incr = (1 << 12);
71 cpu_data->dcache.entry_mask = 0xff0; 71 current_cpu_data.dcache.entry_mask = 0xff0;
72 cpu_data->dcache.sets = 256; 72 current_cpu_data.dcache.sets = 256;
73 cpu_data->type = CPU_SH7729; 73 current_cpu_data.type = CPU_SH7729;
74 74
75#if defined(CONFIG_CPU_SUBTYPE_SH7706) 75#if defined(CONFIG_CPU_SUBTYPE_SH7706)
76 cpu_data->type = CPU_SH7706; 76 current_cpu_data.type = CPU_SH7706;
77#endif 77#endif
78#if defined(CONFIG_CPU_SUBTYPE_SH7710) 78#if defined(CONFIG_CPU_SUBTYPE_SH7710)
79 cpu_data->type = CPU_SH7710; 79 current_cpu_data.type = CPU_SH7710;
80#endif 80#endif
81#if defined(CONFIG_CPU_SUBTYPE_SH7705) 81#if defined(CONFIG_CPU_SUBTYPE_SH7705)
82 cpu_data->type = CPU_SH7705; 82 current_cpu_data.type = CPU_SH7705;
83 83
84#if defined(CONFIG_SH7705_CACHE_32KB) 84#if defined(CONFIG_SH7705_CACHE_32KB)
85 cpu_data->dcache.way_incr = (1 << 13); 85 current_cpu_data.dcache.way_incr = (1 << 13);
86 cpu_data->dcache.entry_mask = 0x1ff0; 86 current_cpu_data.dcache.entry_mask = 0x1ff0;
87 cpu_data->dcache.sets = 512; 87 current_cpu_data.dcache.sets = 512;
88 ctrl_outl(CCR_CACHE_32KB, CCR3); 88 ctrl_outl(CCR_CACHE_32KB, CCR3);
89#else 89#else
90 ctrl_outl(CCR_CACHE_16KB, CCR3); 90 ctrl_outl(CCR_CACHE_16KB, CCR3);
@@ -95,8 +95,8 @@ int __init detect_cpu_and_cache_system(void)
95 /* 95 /*
96 * SH-3 doesn't have separate caches 96 * SH-3 doesn't have separate caches
97 */ 97 */
98 cpu_data->dcache.flags |= SH_CACHE_COMBINED; 98 current_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
99 cpu_data->icache = cpu_data->dcache; 99 current_cpu_data.icache = current_cpu_data.dcache;
100 100
101 return 0; 101 return 0;
102} 102}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
index ff43ef2a1f0c..dc9b211cf87f 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
@@ -51,3 +51,24 @@ static int __init sh7709_devices_setup(void)
51 ARRAY_SIZE(sh7709_devices)); 51 ARRAY_SIZE(sh7709_devices));
52} 52}
53__initcall(sh7709_devices_setup); 53__initcall(sh7709_devices_setup);
54
55#define IPRx(A,N) .addr=A, .shift=0*N*-1
56#define IPRA(N) IPRx(0xfffffee2UL,N)
57#define IPRB(N) IPRx(0xfffffee4UL,N)
58#define IPRE(N) IPRx(0xa400001aUL,N)
59
60static struct ipr_data sh7709_ipr_map[] = {
61 [16] = { IPRA(15-12), 2 }, /* TMU TUNI0 */
62 [17] = { IPRA(11-8), 4 }, /* TMU TUNI1 */
63 [22] = { IPRA(3-0), 2 }, /* RTC CUI */
64 [23 ... 26] = { IPRB(7-4), 3 }, /* SCI */
65 [27] = { IPRB(15-12), 2 }, /* WDT ITI */
66 [48 ... 51] = { IPRE(15-12), 7 }, /* DMA */
67 [52 ... 55] = { IPRE(11-8), 3 }, /* IRDA */
68 [56 ... 59] = { IPRE(7-4), 3 }, /* SCIF */
69};
70
71void __init init_IRQ_ipr()
72{
73 make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map));
74}
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 9031a22a2ce7..9d28c88d2f9d 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -10,11 +10,10 @@
10 * License. See the file "COPYING" in the main directory of this archive 10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details. 11 * for more details.
12 */ 12 */
13
14#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h>
15#include <asm/processor.h> 15#include <asm/processor.h>
16#include <asm/cache.h> 16#include <asm/cache.h>
17#include <asm/io.h>
18 17
19int __init detect_cpu_and_cache_system(void) 18int __init detect_cpu_and_cache_system(void)
20{ 19{
@@ -36,20 +35,20 @@ int __init detect_cpu_and_cache_system(void)
36 /* 35 /*
37 * Setup some sane SH-4 defaults for the icache 36 * Setup some sane SH-4 defaults for the icache
38 */ 37 */
39 cpu_data->icache.way_incr = (1 << 13); 38 current_cpu_data.icache.way_incr = (1 << 13);
40 cpu_data->icache.entry_shift = 5; 39 current_cpu_data.icache.entry_shift = 5;
41 cpu_data->icache.sets = 256; 40 current_cpu_data.icache.sets = 256;
42 cpu_data->icache.ways = 1; 41 current_cpu_data.icache.ways = 1;
43 cpu_data->icache.linesz = L1_CACHE_BYTES; 42 current_cpu_data.icache.linesz = L1_CACHE_BYTES;
44 43
45 /* 44 /*
46 * And again for the dcache .. 45 * And again for the dcache ..
47 */ 46 */
48 cpu_data->dcache.way_incr = (1 << 14); 47 current_cpu_data.dcache.way_incr = (1 << 14);
49 cpu_data->dcache.entry_shift = 5; 48 current_cpu_data.dcache.entry_shift = 5;
50 cpu_data->dcache.sets = 512; 49 current_cpu_data.dcache.sets = 512;
51 cpu_data->dcache.ways = 1; 50 current_cpu_data.dcache.ways = 1;
52 cpu_data->dcache.linesz = L1_CACHE_BYTES; 51 current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
53 52
54 /* 53 /*
55 * Setup some generic flags we can probe 54 * Setup some generic flags we can probe
@@ -57,16 +56,16 @@ int __init detect_cpu_and_cache_system(void)
57 */ 56 */
58 if (((pvr >> 16) & 0xff) == 0x10) { 57 if (((pvr >> 16) & 0xff) == 0x10) {
59 if ((cvr & 0x02000000) == 0) 58 if ((cvr & 0x02000000) == 0)
60 cpu_data->flags |= CPU_HAS_L2_CACHE; 59 current_cpu_data.flags |= CPU_HAS_L2_CACHE;
61 if ((cvr & 0x10000000) == 0) 60 if ((cvr & 0x10000000) == 0)
62 cpu_data->flags |= CPU_HAS_DSP; 61 current_cpu_data.flags |= CPU_HAS_DSP;
63 62
64 cpu_data->flags |= CPU_HAS_LLSC; 63 current_cpu_data.flags |= CPU_HAS_LLSC;
65 } 64 }
66 65
67 /* FPU detection works for everyone */ 66 /* FPU detection works for everyone */
68 if ((cvr & 0x20000000) == 1) 67 if ((cvr & 0x20000000) == 1)
69 cpu_data->flags |= CPU_HAS_FPU; 68 current_cpu_data.flags |= CPU_HAS_FPU;
70 69
71 /* Mask off the upper chip ID */ 70 /* Mask off the upper chip ID */
72 pvr &= 0xffff; 71 pvr &= 0xffff;
@@ -77,151 +76,151 @@ int __init detect_cpu_and_cache_system(void)
77 */ 76 */
78 switch (pvr) { 77 switch (pvr) {
79 case 0x205: 78 case 0x205:
80 cpu_data->type = CPU_SH7750; 79 current_cpu_data.type = CPU_SH7750;
81 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | 80 current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
82 CPU_HAS_PERF_COUNTER; 81 CPU_HAS_PERF_COUNTER;
83 break; 82 break;
84 case 0x206: 83 case 0x206:
85 cpu_data->type = CPU_SH7750S; 84 current_cpu_data.type = CPU_SH7750S;
86 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | 85 current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
87 CPU_HAS_PERF_COUNTER; 86 CPU_HAS_PERF_COUNTER;
88 break; 87 break;
89 case 0x1100: 88 case 0x1100:
90 cpu_data->type = CPU_SH7751; 89 current_cpu_data.type = CPU_SH7751;
91 cpu_data->flags |= CPU_HAS_FPU; 90 current_cpu_data.flags |= CPU_HAS_FPU;
92 break; 91 break;
93 case 0x2000: 92 case 0x2000:
94 cpu_data->type = CPU_SH73180; 93 current_cpu_data.type = CPU_SH73180;
95 cpu_data->icache.ways = 4; 94 current_cpu_data.icache.ways = 4;
96 cpu_data->dcache.ways = 4; 95 current_cpu_data.dcache.ways = 4;
97 cpu_data->flags |= CPU_HAS_LLSC; 96 current_cpu_data.flags |= CPU_HAS_LLSC;
98 break; 97 break;
99 case 0x2001: 98 case 0x2001:
100 case 0x2004: 99 case 0x2004:
101 cpu_data->type = CPU_SH7770; 100 current_cpu_data.type = CPU_SH7770;
102 cpu_data->icache.ways = 4; 101 current_cpu_data.icache.ways = 4;
103 cpu_data->dcache.ways = 4; 102 current_cpu_data.dcache.ways = 4;
104 103
105 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_LLSC; 104 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
106 break; 105 break;
107 case 0x2006: 106 case 0x2006:
108 case 0x200A: 107 case 0x200A:
109 if (prr == 0x61) 108 if (prr == 0x61)
110 cpu_data->type = CPU_SH7781; 109 current_cpu_data.type = CPU_SH7781;
111 else 110 else
112 cpu_data->type = CPU_SH7780; 111 current_cpu_data.type = CPU_SH7780;
113 112
114 cpu_data->icache.ways = 4; 113 current_cpu_data.icache.ways = 4;
115 cpu_data->dcache.ways = 4; 114 current_cpu_data.dcache.ways = 4;
116 115
117 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | 116 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
118 CPU_HAS_LLSC; 117 CPU_HAS_LLSC;
119 break; 118 break;
120 case 0x3000: 119 case 0x3000:
121 case 0x3003: 120 case 0x3003:
122 case 0x3009: 121 case 0x3009:
123 cpu_data->type = CPU_SH7343; 122 current_cpu_data.type = CPU_SH7343;
124 cpu_data->icache.ways = 4; 123 current_cpu_data.icache.ways = 4;
125 cpu_data->dcache.ways = 4; 124 current_cpu_data.dcache.ways = 4;
126 cpu_data->flags |= CPU_HAS_LLSC; 125 current_cpu_data.flags |= CPU_HAS_LLSC;
127 break; 126 break;
128 case 0x3008: 127 case 0x3008:
129 if (prr == 0xa0) { 128 if (prr == 0xa0) {
130 cpu_data->type = CPU_SH7722; 129 current_cpu_data.type = CPU_SH7722;
131 cpu_data->icache.ways = 4; 130 current_cpu_data.icache.ways = 4;
132 cpu_data->dcache.ways = 4; 131 current_cpu_data.dcache.ways = 4;
133 cpu_data->flags |= CPU_HAS_LLSC; 132 current_cpu_data.flags |= CPU_HAS_LLSC;
134 } 133 }
135 break; 134 break;
136 case 0x8000: 135 case 0x8000:
137 cpu_data->type = CPU_ST40RA; 136 current_cpu_data.type = CPU_ST40RA;
138 cpu_data->flags |= CPU_HAS_FPU; 137 current_cpu_data.flags |= CPU_HAS_FPU;
139 break; 138 break;
140 case 0x8100: 139 case 0x8100:
141 cpu_data->type = CPU_ST40GX1; 140 current_cpu_data.type = CPU_ST40GX1;
142 cpu_data->flags |= CPU_HAS_FPU; 141 current_cpu_data.flags |= CPU_HAS_FPU;
143 break; 142 break;
144 case 0x700: 143 case 0x700:
145 cpu_data->type = CPU_SH4_501; 144 current_cpu_data.type = CPU_SH4_501;
146 cpu_data->icache.ways = 2; 145 current_cpu_data.icache.ways = 2;
147 cpu_data->dcache.ways = 2; 146 current_cpu_data.dcache.ways = 2;
148 break; 147 break;
149 case 0x600: 148 case 0x600:
150 cpu_data->type = CPU_SH4_202; 149 current_cpu_data.type = CPU_SH4_202;
151 cpu_data->icache.ways = 2; 150 current_cpu_data.icache.ways = 2;
152 cpu_data->dcache.ways = 2; 151 current_cpu_data.dcache.ways = 2;
153 cpu_data->flags |= CPU_HAS_FPU; 152 current_cpu_data.flags |= CPU_HAS_FPU;
154 break; 153 break;
155 case 0x500 ... 0x501: 154 case 0x500 ... 0x501:
156 switch (prr) { 155 switch (prr) {
157 case 0x10: 156 case 0x10:
158 cpu_data->type = CPU_SH7750R; 157 current_cpu_data.type = CPU_SH7750R;
159 break; 158 break;
160 case 0x11: 159 case 0x11:
161 cpu_data->type = CPU_SH7751R; 160 current_cpu_data.type = CPU_SH7751R;
162 break; 161 break;
163 case 0x50 ... 0x5f: 162 case 0x50 ... 0x5f:
164 cpu_data->type = CPU_SH7760; 163 current_cpu_data.type = CPU_SH7760;
165 break; 164 break;
166 } 165 }
167 166
168 cpu_data->icache.ways = 2; 167 current_cpu_data.icache.ways = 2;
169 cpu_data->dcache.ways = 2; 168 current_cpu_data.dcache.ways = 2;
170 169
171 cpu_data->flags |= CPU_HAS_FPU; 170 current_cpu_data.flags |= CPU_HAS_FPU;
172 171
173 break; 172 break;
174 default: 173 default:
175 cpu_data->type = CPU_SH_NONE; 174 current_cpu_data.type = CPU_SH_NONE;
176 break; 175 break;
177 } 176 }
178 177
179#ifdef CONFIG_SH_DIRECT_MAPPED 178#ifdef CONFIG_SH_DIRECT_MAPPED
180 cpu_data->icache.ways = 1; 179 current_cpu_data.icache.ways = 1;
181 cpu_data->dcache.ways = 1; 180 current_cpu_data.dcache.ways = 1;
182#endif 181#endif
183 182
184#ifdef CONFIG_CPU_HAS_PTEA 183#ifdef CONFIG_CPU_HAS_PTEA
185 cpu_data->flags |= CPU_HAS_PTEA; 184 current_cpu_data.flags |= CPU_HAS_PTEA;
186#endif 185#endif
187 186
188 /* 187 /*
189 * On anything that's not a direct-mapped cache, look to the CVR 188 * On anything that's not a direct-mapped cache, look to the CVR
190 * for I/D-cache specifics. 189 * for I/D-cache specifics.
191 */ 190 */
192 if (cpu_data->icache.ways > 1) { 191 if (current_cpu_data.icache.ways > 1) {
193 size = sizes[(cvr >> 20) & 0xf]; 192 size = sizes[(cvr >> 20) & 0xf];
194 cpu_data->icache.way_incr = (size >> 1); 193 current_cpu_data.icache.way_incr = (size >> 1);
195 cpu_data->icache.sets = (size >> 6); 194 current_cpu_data.icache.sets = (size >> 6);
196 195
197 } 196 }
198 197
199 /* Setup the rest of the I-cache info */ 198 /* Setup the rest of the I-cache info */
200 cpu_data->icache.entry_mask = cpu_data->icache.way_incr - 199 current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr -
201 cpu_data->icache.linesz; 200 current_cpu_data.icache.linesz;
202 201
203 cpu_data->icache.way_size = cpu_data->icache.sets * 202 current_cpu_data.icache.way_size = current_cpu_data.icache.sets *
204 cpu_data->icache.linesz; 203 current_cpu_data.icache.linesz;
205 204
206 /* And the rest of the D-cache */ 205 /* And the rest of the D-cache */
207 if (cpu_data->dcache.ways > 1) { 206 if (current_cpu_data.dcache.ways > 1) {
208 size = sizes[(cvr >> 16) & 0xf]; 207 size = sizes[(cvr >> 16) & 0xf];
209 cpu_data->dcache.way_incr = (size >> 1); 208 current_cpu_data.dcache.way_incr = (size >> 1);
210 cpu_data->dcache.sets = (size >> 6); 209 current_cpu_data.dcache.sets = (size >> 6);
211 } 210 }
212 211
213 cpu_data->dcache.entry_mask = cpu_data->dcache.way_incr - 212 current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr -
214 cpu_data->dcache.linesz; 213 current_cpu_data.dcache.linesz;
215 214
216 cpu_data->dcache.way_size = cpu_data->dcache.sets * 215 current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
217 cpu_data->dcache.linesz; 216 current_cpu_data.dcache.linesz;
218 217
219 /* 218 /*
220 * Setup the L2 cache desc 219 * Setup the L2 cache desc
221 * 220 *
222 * SH-4A's have an optional PIPT L2. 221 * SH-4A's have an optional PIPT L2.
223 */ 222 */
224 if (cpu_data->flags & CPU_HAS_L2_CACHE) { 223 if (current_cpu_data.flags & CPU_HAS_L2_CACHE) {
225 /* 224 /*
226 * Size calculation is much more sensible 225 * Size calculation is much more sensible
227 * than it is for the L1. 226 * than it is for the L1.
@@ -232,16 +231,22 @@ int __init detect_cpu_and_cache_system(void)
232 231
233 BUG_ON(!size); 232 BUG_ON(!size);
234 233
235 cpu_data->scache.way_incr = (1 << 16); 234 current_cpu_data.scache.way_incr = (1 << 16);
236 cpu_data->scache.entry_shift = 5; 235 current_cpu_data.scache.entry_shift = 5;
237 cpu_data->scache.ways = 4; 236 current_cpu_data.scache.ways = 4;
238 cpu_data->scache.linesz = L1_CACHE_BYTES; 237 current_cpu_data.scache.linesz = L1_CACHE_BYTES;
239 cpu_data->scache.entry_mask = 238
240 (cpu_data->scache.way_incr - cpu_data->scache.linesz); 239 current_cpu_data.scache.entry_mask =
241 cpu_data->scache.sets = size / 240 (current_cpu_data.scache.way_incr -
242 (cpu_data->scache.linesz * cpu_data->scache.ways); 241 current_cpu_data.scache.linesz);
243 cpu_data->scache.way_size = 242
244 (cpu_data->scache.sets * cpu_data->scache.linesz); 243 current_cpu_data.scache.sets = size /
244 (current_cpu_data.scache.linesz *
245 current_cpu_data.scache.ways);
246
247 current_cpu_data.scache.way_size =
248 (current_cpu_data.scache.sets *
249 current_cpu_data.scache.linesz);
245 } 250 }
246 251
247 return 0; 252 return 0;
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index cbac27634c0b..6f8f458912c7 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -46,11 +46,13 @@ static struct platform_device rtc_device = {
46 46
47static struct plat_sci_port sci_platform_data[] = { 47static struct plat_sci_port sci_platform_data[] = {
48 { 48 {
49#ifndef CONFIG_SH_RTS7751R2D
49 .mapbase = 0xffe00000, 50 .mapbase = 0xffe00000,
50 .flags = UPF_BOOT_AUTOCONF, 51 .flags = UPF_BOOT_AUTOCONF,
51 .type = PORT_SCI, 52 .type = PORT_SCI,
52 .irqs = { 23, 24, 25, 0 }, 53 .irqs = { 23, 24, 25, 0 },
53 }, { 54 }, {
55#endif
54 .mapbase = 0xffe80000, 56 .mapbase = 0xffe80000,
55 .flags = UPF_BOOT_AUTOCONF, 57 .flags = UPF_BOOT_AUTOCONF,
56 .type = PORT_SCIF, 58 .type = PORT_SCIF,
@@ -101,7 +103,7 @@ static struct ipr_data sh7750_ipr_map[] = {
101 { 35, 2, 8, 7 }, /* DMAC DMTE1 */ 103 { 35, 2, 8, 7 }, /* DMAC DMTE1 */
102 { 36, 2, 8, 7 }, /* DMAC DMTE2 */ 104 { 36, 2, 8, 7 }, /* DMAC DMTE2 */
103 { 37, 2, 8, 7 }, /* DMAC DMTE3 */ 105 { 37, 2, 8, 7 }, /* DMAC DMTE3 */
104 { 28, 2, 8, 7 }, /* DMAC DMAE */ 106 { 38, 2, 8, 7 }, /* DMAC DMAE */
105}; 107};
106 108
107static struct ipr_data sh7751_ipr_map[] = { 109static struct ipr_data sh7751_ipr_map[] = {
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 07e5377bf550..b7c702821e6f 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -52,17 +52,11 @@ static int __init sh7760_devices_setup(void)
52} 52}
53__initcall(sh7760_devices_setup); 53__initcall(sh7760_devices_setup);
54 54
55/*
56 * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
57 */
58static struct intc2_data intc2_irq_table[] = { 55static struct intc2_data intc2_irq_table[] = {
59 /* INTPRIO0 | INTMSK0 */
60 {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ 56 {48, 0, 28, 0, 31, 3}, /* IRQ 4 */
61 {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ 57 {49, 0, 24, 0, 30, 3}, /* IRQ 3 */
62 {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ 58 {50, 0, 20, 0, 29, 3}, /* IRQ 2 */
63 {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ 59 {51, 0, 16, 0, 28, 3}, /* IRQ 1 */
64 /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
65 /* INTPRIO4 | INTMSK0 */
66 {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ 60 {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */
67 {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ 61 {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */
68 {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ 62 {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */
@@ -71,18 +65,15 @@ static struct intc2_data intc2_irq_table[] = {
71 {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ 65 {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */
72 {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ 66 {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */
73 {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ 67 {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */
74 /* INTPRIO8 | INTMSK0 */
75 {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ 68 {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */
76 {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ 69 {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */
77 {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ 70 {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */
78 {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ 71 {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */
79 {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ 72 {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */
80 {65, 8, 24, 0, 16, 3}, /* LCDC */ 73 {65, 8, 24, 0, 16, 3}, /* LCDC */
81 /* 66, 67 unused */
82 {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ 74 {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */
83 {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ 75 {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */
84 {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ 76 {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */
85 /* 71 unused */
86 {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ 77 {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */
87 {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ 78 {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */
88 {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ 79 {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */
@@ -91,26 +82,71 @@ static struct intc2_data intc2_irq_table[] = {
91 {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ 82 {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */
92 {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ 83 {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */
93 {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ 84 {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */
94 /* | INTMSK4 */
95 {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ 85 {80, 8, 4, 4, 23, 3}, /* SIM_ERI */
96 {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ 86 {81, 8, 4, 4, 22, 3}, /* SIM_RXI */
97 {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ 87 {82, 8, 4, 4, 21, 3}, /* SIM_TXI */
98 {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ 88 {83, 8, 4, 4, 20, 3}, /* SIM_TEI */
99 {84, 8, 0, 4, 19, 3}, /* HSPII */ 89 {84, 8, 0, 4, 19, 3}, /* HSPII */
100 /* INTPRIOC | INTMSK4 */
101 /* 85-87 unused/reserved */
102 {88, 12, 20, 4, 18, 3}, /* MMCI0 */ 90 {88, 12, 20, 4, 18, 3}, /* MMCI0 */
103 {89, 12, 20, 4, 17, 3}, /* MMCI1 */ 91 {89, 12, 20, 4, 17, 3}, /* MMCI1 */
104 {90, 12, 20, 4, 16, 3}, /* MMCI2 */ 92 {90, 12, 20, 4, 16, 3}, /* MMCI2 */
105 {91, 12, 20, 4, 15, 3}, /* MMCI3 */ 93 {91, 12, 20, 4, 15, 3}, /* MMCI3 */
106 {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ 94 {92, 12, 12, 4, 6, 3}, /* MFI */
107 /* 93-107 reserved/undocumented */
108 {108,12, 4, 4, 1, 3}, /* ADC */ 95 {108,12, 4, 4, 1, 3}, /* ADC */
109 {109,12, 0, 4, 0, 3}, /* CMTI */ 96 {109,12, 0, 4, 0, 3}, /* CMTI */
110 /* 110-111 reserved/unused */
111}; 97};
112 98
99static struct ipr_data sh7760_ipr_map[] = {
100 /* IRQ, IPR-idx, shift, priority */
101 { 16, 0, 12, 2 }, /* TMU0 TUNI*/
102 { 17, 0, 8, 2 }, /* TMU1 TUNI */
103 { 18, 0, 4, 2 }, /* TMU2 TUNI */
104 { 19, 0, 4, 2 }, /* TMU2 TIPCI */
105 { 27, 1, 12, 2 }, /* WDT ITI */
106 { 28, 1, 8, 2 }, /* REF RCMI */
107 { 29, 1, 8, 2 }, /* REF ROVI */
108 { 32, 2, 0, 7 }, /* HUDI */
109 { 33, 2, 12, 7 }, /* GPIOI */
110 { 34, 2, 8, 7 }, /* DMAC DMTE0 */
111 { 35, 2, 8, 7 }, /* DMAC DMTE1 */
112 { 36, 2, 8, 7 }, /* DMAC DMTE2 */
113 { 37, 2, 8, 7 }, /* DMAC DMTE3 */
114 { 38, 2, 8, 7 }, /* DMAC DMAE */
115 { 44, 2, 8, 7 }, /* DMAC DMTE4 */
116 { 45, 2, 8, 7 }, /* DMAC DMTE5 */
117 { 46, 2, 8, 7 }, /* DMAC DMTE6 */
118 { 47, 2, 8, 7 }, /* DMAC DMTE7 */
119/* these here are only valid if INTC_ICR bit 7 is set to 1!
120 * XXX: maybe CONFIG_SH_IRLMODE symbol? SH7751 could use it too */
121#if 0
122 { 2, 3, 12, 3 }, /* IRL0 */
123 { 5, 3, 8, 3 }, /* IRL1 */
124 { 8, 3, 4, 3 }, /* IRL2 */
125 { 11, 3, 0, 3 }, /* IRL3 */
126#endif
127};
128
129static unsigned long ipr_offsets[] = {
130 0xffd00004UL, /* 0: IPRA */
131 0xffd00008UL, /* 1: IPRB */
132 0xffd0000cUL, /* 2: IPRC */
133 0xffd00010UL, /* 3: IPRD */
134};
135
136/* given the IPR index return the address of the IPR register */
137unsigned int map_ipridx_to_addr(int idx)
138{
139 if (idx >= ARRAY_SIZE(ipr_offsets))
140 return 0;
141 return ipr_offsets[idx];
142}
143
113void __init init_IRQ_intc2(void) 144void __init init_IRQ_intc2(void)
114{ 145{
115 make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); 146 make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
116} 147}
148
149void __init init_IRQ_ipr(void)
150{
151 make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map));
152}
diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S
new file mode 100644
index 000000000000..13b66746410a
--- /dev/null
+++ b/arch/sh/kernel/debugtraps.S
@@ -0,0 +1,41 @@
1/*
2 * arch/sh/kernel/debugtraps.S
3 *
4 * Debug trap jump tables for SuperH
5 *
6 * Copyright (C) 2006 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/sys.h>
13#include <linux/linkage.h>
14
15#if !defined(CONFIG_SH_KGDB)
16#define kgdb_handle_exception debug_trap_handler
17#endif
18
19#if !defined(CONFIG_SH_STANDARD_BIOS)
20#define sh_bios_handler debug_trap_handler
21#endif
22
23 .data
24
25ENTRY(debug_trap_table)
26 .long debug_trap_handler /* 0x30 */
27 .long debug_trap_handler /* 0x31 */
28 .long debug_trap_handler /* 0x32 */
29 .long debug_trap_handler /* 0x33 */
30 .long debug_trap_handler /* 0x34 */
31 .long debug_trap_handler /* 0x35 */
32 .long debug_trap_handler /* 0x36 */
33 .long debug_trap_handler /* 0x37 */
34 .long debug_trap_handler /* 0x38 */
35 .long debug_trap_handler /* 0x39 */
36 .long debug_trap_handler /* 0x3a */
37 .long debug_trap_handler /* 0x3b */
38 .long kgdb_handle_exception /* 0x3c */
39 .long debug_trap_handler /* 0x3d */
40 .long bug_trap_handler /* 0x3e */
41 .long sh_bios_handler /* 0x3f */
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 560b91cdd15c..9048c0326d87 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -106,12 +106,32 @@ static struct console scif_console = {
106}; 106};
107 107
108#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) 108#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
109#define DEFAULT_BAUD 115200
109/* 110/*
110 * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 111 * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
111 * devices that aren't using sh-ipl+g. 112 * devices that aren't using sh-ipl+g.
112 */ 113 */
113static void scif_sercon_init(int baud) 114static void scif_sercon_init(char *s)
114{ 115{
116 unsigned baud = DEFAULT_BAUD;
117 char *e;
118
119 if (*s == ',')
120 ++s;
121
122 if (*s) {
123 /* ignore ioport/device name */
124 s += strcspn(s, ",");
125 if (*s == ',')
126 s++;
127 }
128
129 if (*s) {
130 baud = simple_strtoul(s, &e, 0);
131 if (baud == 0 || s == e)
132 baud = DEFAULT_BAUD;
133 }
134
115 ctrl_outw(0, scif_port.mapbase + 8); 135 ctrl_outw(0, scif_port.mapbase + 8);
116 ctrl_outw(0, scif_port.mapbase); 136 ctrl_outw(0, scif_port.mapbase);
117 137
@@ -167,7 +187,7 @@ int __init setup_early_printk(char *buf)
167 early_console = &scif_console; 187 early_console = &scif_console;
168 188
169#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) 189#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
170 scif_sercon_init(115200); 190 scif_sercon_init(buf + 6);
171#endif 191#endif
172 } 192 }
173#endif 193#endif
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index fc279aeb73ab..ab4ebb856c2a 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -54,79 +54,24 @@
54# define resume_kernel __restore_all 54# define resume_kernel __restore_all
55#endif 55#endif
56 56
57#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
58! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
59! If both are configured, handle the debug traps (breakpoints) in SW,
60! but still allow BIOS traps to FW.
61
62 .align 2
63debug_kernel:
64#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
65 /* Force BIOS call to FW (debug_trap put TRA in r8) */
66 mov r8,r0
67 shlr2 r0
68 cmp/eq #0x3f,r0
69 bt debug_kernel_fw
70#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
71
72debug_enter:
73#if defined(CONFIG_SH_KGDB)
74 /* Jump to kgdb, pass stacked regs as arg */
75debug_kernel_sw:
76 mov.l 3f, r0
77 jmp @r0
78 mov r15, r4
79 .align 2
803: .long kgdb_handle_exception
81#endif /* CONFIG_SH_KGDB */
82#ifdef CONFIG_SH_STANDARD_BIOS
83 bra debug_kernel_fw
84 nop
85#endif
86#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
87
88 .align 2
89debug_trap:
90#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
91 mov r8, r0
92 shlr2 r0
93 cmp/eq #0x3f, r0 ! sh_bios() trap
94 bf 1f
95#ifdef CONFIG_SH_KGDB
96 cmp/eq #0xff, r0 ! XXX: KGDB trap, fix for SH-2.
97 bf 1f
98#endif
99 mov #OFF_SR, r0
100 mov.l @(r0,r15), r0 ! get status register
101 shll r0
102 shll r0 ! kernel space?
103 bt/s debug_kernel
1041:
105#endif
106 mov.l @r15, r0 ! Restore R0 value
107 mov.l 1f, r8
108 jmp @r8
109 nop
110 57
111 .align 2 58 .align 2
112ENTRY(exception_error) 59ENTRY(exception_error)
113 ! 60 !
114#ifdef CONFIG_TRACE_IRQFLAGS 61#ifdef CONFIG_TRACE_IRQFLAGS
115 mov.l 3f, r0 62 mov.l 2f, r0
116 jsr @r0 63 jsr @r0
117 nop 64 nop
118#endif 65#endif
119 sti 66 sti
120 mov.l 2f, r0 67 mov.l 1f, r0
121 jmp @r0 68 jmp @r0
122 nop 69 nop
123 70
124!
125 .align 2 71 .align 2
1261: .long break_point_trap_software 721: .long do_exception_error
1272: .long do_exception_error
128#ifdef CONFIG_TRACE_IRQFLAGS 73#ifdef CONFIG_TRACE_IRQFLAGS
1293: .long trace_hardirqs_on 742: .long trace_hardirqs_on
130#endif 75#endif
131 76
132 .align 2 77 .align 2
@@ -331,16 +276,31 @@ __restore_all:
3311: .long restore_all 2761: .long restore_all
332 277
333 .align 2 278 .align 2
334not_syscall_tra:
335 bra debug_trap
336 nop
337
338 .align 2
339syscall_badsys: ! Bad syscall number 279syscall_badsys: ! Bad syscall number
340 mov #-ENOSYS, r0 280 mov #-ENOSYS, r0
341 bra resume_userspace 281 bra resume_userspace
342 mov.l r0, @(OFF_R0,r15) ! Return value 282 mov.l r0, @(OFF_R0,r15) ! Return value
343 283
284/*
285 * The main debug trap handler.
286 *
287 * r8=TRA (not the trap number!)
288 *
289 * Note: This assumes that the trapa value is left in its original
290 * form (without the shlr2 shift) so the calculation for the jump
291 * call table offset remains a simple in place mask.
292 */
293debug_trap:
294 mov r8, r0
295 and #(0xf << 2), r0
296 mov.l 1f, r8
297 add r0, r8
298 mov.l @r8, r8
299 jmp @r8
300 nop
301
302 .align 2
3031: .long debug_trap_table
344 304
345/* 305/*
346 * Syscall interface: 306 * Syscall interface:
@@ -348,17 +308,19 @@ syscall_badsys: ! Bad syscall number
348 * Syscall #: R3 308 * Syscall #: R3
349 * Arguments #0 to #3: R4--R7 309 * Arguments #0 to #3: R4--R7
350 * Arguments #4 to #6: R0, R1, R2 310 * Arguments #4 to #6: R0, R1, R2
351 * TRA: (number of arguments + 0x10) x 4 311 * TRA: (number of arguments + ABI revision) x 4
352 * 312 *
353 * This code also handles delegating other traps to the BIOS/gdb stub 313 * This code also handles delegating other traps to the BIOS/gdb stub
354 * according to: 314 * according to:
355 * 315 *
356 * Trap number 316 * Trap number
357 * (TRA>>2) Purpose 317 * (TRA>>2) Purpose
358 * -------- ------- 318 * -------- -------
359 * 0x0-0xf old syscall ABI 319 * 0x00-0x0f original SH-3/4 syscall ABI (not in general use).
360 * 0x10-0x1f new syscall ABI 320 * 0x10-0x1f general SH-3/4 syscall ABI.
361 * 0x20-0xff delegated through debug_trap to BIOS/gdb stub. 321 * 0x20-0x2f syscall ABI for SH-2 parts.
322 * 0x30-0x3f debug traps used by the kernel.
323 * 0x40-0xff Not supported by all parts, so left unhandled.
362 * 324 *
363 * Note: When we're first called, the TRA value must be shifted 325 * Note: When we're first called, the TRA value must be shifted
364 * right 2 bits in order to get the value that was used as the "trapa" 326 * right 2 bits in order to get the value that was used as the "trapa"
@@ -375,17 +337,22 @@ ret_from_fork:
375 nop 337 nop
376 .align 2 338 .align 2
3771: .long schedule_tail 3391: .long schedule_tail
378 ! 340
341/*
342 * The poorly named main trapa decode and dispatch routine, for
343 * system calls and debug traps through their respective jump tables.
344 */
379ENTRY(system_call) 345ENTRY(system_call)
380#if !defined(CONFIG_CPU_SH2) 346#if !defined(CONFIG_CPU_SH2)
381 mov.l 1f, r9 347 mov.l 1f, r9
382 mov.l @r9, r8 ! Read from TRA (Trap Address) Register 348 mov.l @r9, r8 ! Read from TRA (Trap Address) Register
383#endif 349#endif
384 ! 350 /*
385 ! Is the trap argument >= 0x20? (TRA will be >= 0x80) 351 * Check the trap type
386 mov #0x7f, r9 352 */
353 mov #((0x20 << 2) - 1), r9
387 cmp/hi r9, r8 354 cmp/hi r9, r8
388 bt/s not_syscall_tra 355 bt/s debug_trap ! it's a debug trap..
389 mov #OFF_TRA, r9 356 mov #OFF_TRA, r9
390 add r15, r9 357 add r15, r9
391 mov.l r8, @r9 ! set TRA value to tra 358 mov.l r8, @r9 ! set TRA value to tra
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 28ec7487de8c..66626c03e1ee 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -1,9 +1,8 @@
1/* $Id: io_generic.c,v 1.2 2003/05/04 19:29:53 lethal Exp $ 1/*
2 * 2 * arch/sh/kernel/io_generic.c
3 * linux/arch/sh/kernel/io_generic.c
4 * 3 *
5 * Copyright (C) 2000 Niibe Yutaka 4 * Copyright (C) 2000 Niibe Yutaka
6 * Copyright (C) 2005 Paul Mundt 5 * Copyright (C) 2005 - 2007 Paul Mundt
7 * 6 *
8 * Generic I/O routine. These can be used where a machine specific version 7 * Generic I/O routine. These can be used where a machine specific version
9 * is not required. 8 * is not required.
@@ -13,8 +12,9 @@
13 * for more details. 12 * for more details.
14 */ 13 */
15#include <linux/module.h> 14#include <linux/module.h>
16#include <asm/io.h> 15#include <linux/io.h>
17#include <asm/machvec.h> 16#include <asm/machvec.h>
17#include <asm/cacheflush.h>
18 18
19#ifdef CONFIG_CPU_SH3 19#ifdef CONFIG_CPU_SH3
20/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a 20/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
@@ -96,6 +96,7 @@ void generic_insw(unsigned long port, void *dst, unsigned long count)
96 while (count--) 96 while (count--)
97 *buf++ = *port_addr; 97 *buf++ = *port_addr;
98 98
99 flush_dcache_all();
99 dummy_read(); 100 dummy_read();
100} 101}
101 102
@@ -170,6 +171,7 @@ void generic_outsw(unsigned long port, const void *src, unsigned long count)
170 while (count--) 171 while (count--)
171 *port_addr = *buf++; 172 *port_addr = *buf++;
172 173
174 flush_dcache_all();
173 dummy_read(); 175 dummy_read();
174} 176}
175 177
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index 9c6315f0335d..d8927d85492e 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -1323,8 +1323,11 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
1323} 1323}
1324 1324
1325/* There has been an exception, most likely a breakpoint. */ 1325/* There has been an exception, most likely a breakpoint. */
1326void kgdb_handle_exception(struct pt_regs *regs) 1326asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
1327 unsigned long r6, unsigned long r7,
1328 struct pt_regs __regs)
1327{ 1329{
1330 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
1328 int excep_code, vbr_val; 1331 int excep_code, vbr_val;
1329 int count; 1332 int count;
1330 int trapa_value = ctrl_inl(TRA); 1333 int trapa_value = ctrl_inl(TRA);
@@ -1368,8 +1371,6 @@ void kgdb_handle_exception(struct pt_regs *regs)
1368 1371
1369 vbr_val = trap_registers.vbr; 1372 vbr_val = trap_registers.vbr;
1370 asm("ldc %0, vbr": :"r"(vbr_val)); 1373 asm("ldc %0, vbr": :"r"(vbr_val));
1371
1372 return;
1373} 1374}
1374 1375
1375/* Trigger a breakpoint by function */ 1376/* Trigger a breakpoint by function */
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 486c06e18033..9d6a438b3eaf 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -1,42 +1,30 @@
1/* $Id: process.c,v 1.28 2004/05/05 16:54:23 lethal Exp $ 1/*
2 * arch/sh/kernel/process.c
2 * 3 *
3 * linux/arch/sh/kernel/process.c 4 * This file handles the architecture-dependent parts of process handling..
4 * 5 *
5 * Copyright (C) 1995 Linus Torvalds 6 * Copyright (C) 1995 Linus Torvalds
6 * 7 *
7 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima 8 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
8 * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC 9 * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
10 * Copyright (C) 2002 - 2006 Paul Mundt
9 */ 11 */
10
11/*
12 * This file handles the architecture-dependent parts of process handling..
13 */
14
15#include <linux/module.h> 12#include <linux/module.h>
16#include <linux/unistd.h>
17#include <linux/mm.h> 13#include <linux/mm.h>
18#include <linux/elfcore.h> 14#include <linux/elfcore.h>
19#include <linux/a.out.h>
20#include <linux/slab.h>
21#include <linux/pm.h> 15#include <linux/pm.h>
22#include <linux/ptrace.h>
23#include <linux/kallsyms.h> 16#include <linux/kallsyms.h>
24#include <linux/kexec.h> 17#include <linux/kexec.h>
25
26#include <asm/io.h>
27#include <asm/uaccess.h> 18#include <asm/uaccess.h>
28#include <asm/mmu_context.h> 19#include <asm/mmu_context.h>
29#include <asm/elf.h>
30#include <asm/ubc.h> 20#include <asm/ubc.h>
31 21
32static int hlt_counter=0; 22static int hlt_counter;
33
34int ubc_usercnt = 0; 23int ubc_usercnt = 0;
35 24
36#define HARD_IDLE_TIMEOUT (HZ / 3) 25#define HARD_IDLE_TIMEOUT (HZ / 3)
37 26
38void (*pm_idle)(void); 27void (*pm_idle)(void);
39
40void (*pm_power_off)(void); 28void (*pm_power_off)(void);
41EXPORT_SYMBOL(pm_power_off); 29EXPORT_SYMBOL(pm_power_off);
42 30
@@ -44,14 +32,12 @@ void disable_hlt(void)
44{ 32{
45 hlt_counter++; 33 hlt_counter++;
46} 34}
47
48EXPORT_SYMBOL(disable_hlt); 35EXPORT_SYMBOL(disable_hlt);
49 36
50void enable_hlt(void) 37void enable_hlt(void)
51{ 38{
52 hlt_counter--; 39 hlt_counter--;
53} 40}
54
55EXPORT_SYMBOL(enable_hlt); 41EXPORT_SYMBOL(enable_hlt);
56 42
57void default_idle(void) 43void default_idle(void)
@@ -152,19 +138,21 @@ __asm__(".align 5\n"
152 ".align 2\n\t" 138 ".align 2\n\t"
153 "1:.long do_exit"); 139 "1:.long do_exit");
154 140
141/* Don't use this in BL=1(cli). Or else, CPU resets! */
155int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 142int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
156{ /* Don't use this in BL=1(cli). Or else, CPU resets! */ 143{
157 struct pt_regs regs; 144 struct pt_regs regs;
158 145
159 memset(&regs, 0, sizeof(regs)); 146 memset(&regs, 0, sizeof(regs));
160 regs.regs[4] = (unsigned long) arg; 147 regs.regs[4] = (unsigned long)arg;
161 regs.regs[5] = (unsigned long) fn; 148 regs.regs[5] = (unsigned long)fn;
162 149
163 regs.pc = (unsigned long) kernel_thread_helper; 150 regs.pc = (unsigned long)kernel_thread_helper;
164 regs.sr = (1 << 30); 151 regs.sr = (1 << 30);
165 152
166 /* Ok, create the new process.. */ 153 /* Ok, create the new process.. */
167 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 154 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
155 &regs, 0, NULL, NULL);
168} 156}
169 157
170/* 158/*
@@ -211,21 +199,20 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
211 return fpvalid; 199 return fpvalid;
212} 200}
213 201
214/* 202/*
215 * Capture the user space registers if the task is not running (in user space) 203 * Capture the user space registers if the task is not running (in user space)
216 */ 204 */
217int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) 205int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
218{ 206{
219 struct pt_regs ptregs; 207 struct pt_regs ptregs;
220 208
221 ptregs = *task_pt_regs(tsk); 209 ptregs = *task_pt_regs(tsk);
222 elf_core_copy_regs(regs, &ptregs); 210 elf_core_copy_regs(regs, &ptregs);
223 211
224 return 1; 212 return 1;
225} 213}
226 214
227int 215int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpu)
228dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *fpu)
229{ 216{
230 int fpvalid = 0; 217 int fpvalid = 0;
231 218
@@ -263,12 +250,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
263 childregs->regs[15] = usp; 250 childregs->regs[15] = usp;
264 ti->addr_limit = USER_DS; 251 ti->addr_limit = USER_DS;
265 } else { 252 } else {
266 childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; 253 childregs->regs[15] = (unsigned long)task_stack_page(p) +
254 THREAD_SIZE;
267 ti->addr_limit = KERNEL_DS; 255 ti->addr_limit = KERNEL_DS;
268 } 256 }
269 if (clone_flags & CLONE_SETTLS) { 257
258 if (clone_flags & CLONE_SETTLS)
270 childregs->gbr = childregs->regs[0]; 259 childregs->gbr = childregs->regs[0];
271 } 260
272 childregs->regs[0] = 0; /* Set return value for child */ 261 childregs->regs[0] = 0; /* Set return value for child */
273 262
274 p->thread.sp = (unsigned long) childregs; 263 p->thread.sp = (unsigned long) childregs;
@@ -280,8 +269,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
280} 269}
281 270
282/* Tracing by user break controller. */ 271/* Tracing by user break controller. */
283static void 272static void ubc_set_tracing(int asid, unsigned long pc)
284ubc_set_tracing(int asid, unsigned long pc)
285{ 273{
286#if defined(CONFIG_CPU_SH4A) 274#if defined(CONFIG_CPU_SH4A)
287 unsigned long val; 275 unsigned long val;
@@ -297,7 +285,7 @@ ubc_set_tracing(int asid, unsigned long pc)
297 val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE); 285 val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
298 ctrl_outl(val, UBC_CRR0); 286 ctrl_outl(val, UBC_CRR0);
299 287
300 /* Read UBC register that we writed last. For chekking UBC Register changed */ 288 /* Read UBC register that we wrote last, for checking update */
301 val = ctrl_inl(UBC_CRR0); 289 val = ctrl_inl(UBC_CRR0);
302 290
303#else /* CONFIG_CPU_SH4A */ 291#else /* CONFIG_CPU_SH4A */
@@ -305,13 +293,14 @@ ubc_set_tracing(int asid, unsigned long pc)
305 293
306#ifdef CONFIG_MMU 294#ifdef CONFIG_MMU
307 /* We don't have any ASID settings for the SH-2! */ 295 /* We don't have any ASID settings for the SH-2! */
308 if (cpu_data->type != CPU_SH7604) 296 if (current_cpu_data.type != CPU_SH7604)
309 ctrl_outb(asid, UBC_BASRA); 297 ctrl_outb(asid, UBC_BASRA);
310#endif 298#endif
311 299
312 ctrl_outl(0, UBC_BAMRA); 300 ctrl_outl(0, UBC_BAMRA);
313 301
314 if (cpu_data->type == CPU_SH7729 || cpu_data->type == CPU_SH7710) { 302 if (current_cpu_data.type == CPU_SH7729 ||
303 current_cpu_data.type == CPU_SH7710) {
315 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); 304 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
316 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); 305 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
317 } else { 306 } else {
@@ -325,7 +314,8 @@ ubc_set_tracing(int asid, unsigned long pc)
325 * switch_to(x,y) should switch tasks from x to y. 314 * switch_to(x,y) should switch tasks from x to y.
326 * 315 *
327 */ 316 */
328struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next) 317struct task_struct *__switch_to(struct task_struct *prev,
318 struct task_struct *next)
329{ 319{
330#if defined(CONFIG_SH_FPU) 320#if defined(CONFIG_SH_FPU)
331 unlazy_fpu(prev, task_pt_regs(prev)); 321 unlazy_fpu(prev, task_pt_regs(prev));
@@ -354,7 +344,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
354#ifdef CONFIG_MMU 344#ifdef CONFIG_MMU
355 /* 345 /*
356 * Restore the kernel mode register 346 * Restore the kernel mode register
357 * k7 (r7_bank1) 347 * k7 (r7_bank1)
358 */ 348 */
359 asm volatile("ldc %0, r7_bank" 349 asm volatile("ldc %0, r7_bank"
360 : /* no output */ 350 : /* no output */
@@ -367,7 +357,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
367 else if (next->thread.ubc_pc && next->mm) { 357 else if (next->thread.ubc_pc && next->mm) {
368 int asid = 0; 358 int asid = 0;
369#ifdef CONFIG_MMU 359#ifdef CONFIG_MMU
370 asid |= next->mm->context.id & MMU_CONTEXT_ASID_MASK; 360 asid |= cpu_asid(smp_processor_id(), next->mm);
371#endif 361#endif
372 ubc_set_tracing(asid, next->thread.ubc_pc); 362 ubc_set_tracing(asid, next->thread.ubc_pc);
373 } else { 363 } else {
@@ -405,7 +395,8 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
405 if (!newsp) 395 if (!newsp)
406 newsp = regs->regs[15]; 396 newsp = regs->regs[15];
407 return do_fork(clone_flags, newsp, regs, 0, 397 return do_fork(clone_flags, newsp, regs, 0,
408 (int __user *)parent_tidptr, (int __user *)child_tidptr); 398 (int __user *)parent_tidptr,
399 (int __user *)child_tidptr);
409} 400}
410 401
411/* 402/*
@@ -493,9 +484,27 @@ asmlinkage void break_point_trap(void)
493 force_sig(SIGTRAP, current); 484 force_sig(SIGTRAP, current);
494} 485}
495 486
496asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, 487/*
497 unsigned long r6, unsigned long r7, 488 * Generic trap handler.
498 struct pt_regs __regs) 489 */
490asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5,
491 unsigned long r6, unsigned long r7,
492 struct pt_regs __regs)
493{
494 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
495
496 /* Rewind */
497 regs->pc -= 2;
498
499 force_sig(SIGTRAP, current);
500}
501
502/*
503 * Special handler for BUG() traps.
504 */
505asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5,
506 unsigned long r6, unsigned long r7,
507 struct pt_regs __regs)
499{ 508{
500 struct pt_regs *regs = RELOC_HIDE(&__regs, 0); 509 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
501 510
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index d6b817aa568f..98802ab28211 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -1,14 +1,11 @@
1/* 1/*
2 * linux/arch/sh/kernel/setup.c 2 * arch/sh/kernel/setup.c
3 * 3 *
4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2002, 2003 Paul Mundt
6 */
7
8/*
9 * This file handles the architecture-dependent parts of initialization 4 * This file handles the architecture-dependent parts of initialization
5 *
6 * Copyright (C) 1999 Niibe Yutaka
7 * Copyright (C) 2002 - 2006 Paul Mundt
10 */ 8 */
11
12#include <linux/screen_info.h> 9#include <linux/screen_info.h>
13#include <linux/ioport.h> 10#include <linux/ioport.h>
14#include <linux/init.h> 11#include <linux/init.h>
@@ -395,9 +392,9 @@ static const char *cpu_name[] = {
395 [CPU_SH_NONE] = "Unknown" 392 [CPU_SH_NONE] = "Unknown"
396}; 393};
397 394
398const char *get_cpu_subtype(void) 395const char *get_cpu_subtype(struct sh_cpuinfo *c)
399{ 396{
400 return cpu_name[boot_cpu_data.type]; 397 return cpu_name[c->type];
401} 398}
402 399
403#ifdef CONFIG_PROC_FS 400#ifdef CONFIG_PROC_FS
@@ -407,19 +404,19 @@ static const char *cpu_flags[] = {
407 "ptea", "llsc", "l2", NULL 404 "ptea", "llsc", "l2", NULL
408}; 405};
409 406
410static void show_cpuflags(struct seq_file *m) 407static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
411{ 408{
412 unsigned long i; 409 unsigned long i;
413 410
414 seq_printf(m, "cpu flags\t:"); 411 seq_printf(m, "cpu flags\t:");
415 412
416 if (!cpu_data->flags) { 413 if (!c->flags) {
417 seq_printf(m, " %s\n", cpu_flags[0]); 414 seq_printf(m, " %s\n", cpu_flags[0]);
418 return; 415 return;
419 } 416 }
420 417
421 for (i = 0; cpu_flags[i]; i++) 418 for (i = 0; cpu_flags[i]; i++)
422 if ((cpu_data->flags & (1 << i))) 419 if ((c->flags & (1 << i)))
423 seq_printf(m, " %s", cpu_flags[i+1]); 420 seq_printf(m, " %s", cpu_flags[i+1]);
424 421
425 seq_printf(m, "\n"); 422 seq_printf(m, "\n");
@@ -441,16 +438,20 @@ static void show_cacheinfo(struct seq_file *m, const char *type,
441 */ 438 */
442static int show_cpuinfo(struct seq_file *m, void *v) 439static int show_cpuinfo(struct seq_file *m, void *v)
443{ 440{
444 unsigned int cpu = smp_processor_id(); 441 struct sh_cpuinfo *c = v;
442 unsigned int cpu = c - cpu_data;
443
444 if (!cpu_online(cpu))
445 return 0;
445 446
446 if (!cpu && cpu_online(cpu)) 447 if (cpu == 0)
447 seq_printf(m, "machine\t\t: %s\n", get_system_type()); 448 seq_printf(m, "machine\t\t: %s\n", get_system_type());
448 449
449 seq_printf(m, "processor\t: %d\n", cpu); 450 seq_printf(m, "processor\t: %d\n", cpu);
450 seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); 451 seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
451 seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype()); 452 seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c));
452 453
453 show_cpuflags(m); 454 show_cpuflags(m, c);
454 455
455 seq_printf(m, "cache type\t: "); 456 seq_printf(m, "cache type\t: ");
456 457
@@ -459,22 +460,22 @@ static int show_cpuinfo(struct seq_file *m, void *v)
459 * unified cache on the SH-2 and SH-3, as well as the harvard 460 * unified cache on the SH-2 and SH-3, as well as the harvard
460 * style cache on the SH-4. 461 * style cache on the SH-4.
461 */ 462 */
462 if (boot_cpu_data.icache.flags & SH_CACHE_COMBINED) { 463 if (c->icache.flags & SH_CACHE_COMBINED) {
463 seq_printf(m, "unified\n"); 464 seq_printf(m, "unified\n");
464 show_cacheinfo(m, "cache", boot_cpu_data.icache); 465 show_cacheinfo(m, "cache", c->icache);
465 } else { 466 } else {
466 seq_printf(m, "split (harvard)\n"); 467 seq_printf(m, "split (harvard)\n");
467 show_cacheinfo(m, "icache", boot_cpu_data.icache); 468 show_cacheinfo(m, "icache", c->icache);
468 show_cacheinfo(m, "dcache", boot_cpu_data.dcache); 469 show_cacheinfo(m, "dcache", c->dcache);
469 } 470 }
470 471
471 /* Optional secondary cache */ 472 /* Optional secondary cache */
472 if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) 473 if (c->flags & CPU_HAS_L2_CACHE)
473 show_cacheinfo(m, "scache", boot_cpu_data.scache); 474 show_cacheinfo(m, "scache", c->scache);
474 475
475 seq_printf(m, "bogomips\t: %lu.%02lu\n", 476 seq_printf(m, "bogomips\t: %lu.%02lu\n",
476 boot_cpu_data.loops_per_jiffy/(500000/HZ), 477 c->loops_per_jiffy/(500000/HZ),
477 (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100); 478 (c->loops_per_jiffy/(5000/HZ)) % 100);
478 479
479 return show_clocks(m); 480 return show_clocks(m);
480} 481}
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index e6106239a0fe..fe1b276c97c6 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -105,7 +105,6 @@ EXPORT_SYMBOL(__flush_purge_region);
105EXPORT_SYMBOL(clear_user_page); 105EXPORT_SYMBOL(clear_user_page);
106#endif 106#endif
107 107
108EXPORT_SYMBOL(flush_tlb_page);
109EXPORT_SYMBOL(__down_trylock); 108EXPORT_SYMBOL(__down_trylock);
110 109
111#ifdef CONFIG_SMP 110#ifdef CONFIG_SMP
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 379c88bf5d9a..32f10a03fbb5 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -127,7 +127,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
127{ 127{
128 struct task_struct *tsk = current; 128 struct task_struct *tsk = current;
129 129
130 if (!(cpu_data->flags & CPU_HAS_FPU)) 130 if (!(current_cpu_data.flags & CPU_HAS_FPU))
131 return 0; 131 return 0;
132 132
133 set_used_math(); 133 set_used_math();
@@ -140,7 +140,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
140{ 140{
141 struct task_struct *tsk = current; 141 struct task_struct *tsk = current;
142 142
143 if (!(cpu_data->flags & CPU_HAS_FPU)) 143 if (!(current_cpu_data.flags & CPU_HAS_FPU))
144 return 0; 144 return 0;
145 145
146 if (!used_math()) { 146 if (!used_math()) {
@@ -181,7 +181,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
181#undef COPY 181#undef COPY
182 182
183#ifdef CONFIG_SH_FPU 183#ifdef CONFIG_SH_FPU
184 if (cpu_data->flags & CPU_HAS_FPU) { 184 if (current_cpu_data.flags & CPU_HAS_FPU) {
185 int owned_fp; 185 int owned_fp;
186 struct task_struct *tsk = current; 186 struct task_struct *tsk = current;
187 187
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S
index ca81976e9e34..38fc8cd3ea3a 100644
--- a/arch/sh/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls.S
@@ -319,15 +319,15 @@ ENTRY(sys_call_table)
319 .long sys_mq_getsetattr 319 .long sys_mq_getsetattr
320 .long sys_kexec_load 320 .long sys_kexec_load
321 .long sys_waitid 321 .long sys_waitid
322 .long sys_ni_syscall /* 285 */ 322 .long sys_add_key /* 285 */
323 .long sys_add_key
324 .long sys_request_key 323 .long sys_request_key
325 .long sys_keyctl 324 .long sys_keyctl
326 .long sys_ioprio_set 325 .long sys_ioprio_set
327 .long sys_ioprio_get /* 290 */ 326 .long sys_ioprio_get
328 .long sys_inotify_init 327 .long sys_inotify_init /* 290 */
329 .long sys_inotify_add_watch 328 .long sys_inotify_add_watch
330 .long sys_inotify_rm_watch 329 .long sys_inotify_rm_watch
330 .long sys_ni_syscall
331 .long sys_migrate_pages 331 .long sys_migrate_pages
332 .long sys_openat /* 295 */ 332 .long sys_openat /* 295 */
333 .long sys_mkdirat 333 .long sys_mkdirat
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index ec110157992d..e9f168f60f95 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -156,13 +156,13 @@ static inline void do_bug_verbose(struct pt_regs *regs)
156{ 156{
157} 157}
158#endif /* CONFIG_DEBUG_BUGVERBOSE */ 158#endif /* CONFIG_DEBUG_BUGVERBOSE */
159#endif /* CONFIG_BUG */
160 159
161void handle_BUG(struct pt_regs *regs) 160void handle_BUG(struct pt_regs *regs)
162{ 161{
163 do_bug_verbose(regs); 162 do_bug_verbose(regs);
164 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); 163 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
165} 164}
165#endif /* CONFIG_BUG */
166 166
167/* 167/*
168 * handle an instruction that does an unaligned memory access by emulating the 168 * handle an instruction that does an unaligned memory access by emulating the
@@ -641,7 +641,7 @@ int is_dsp_inst(struct pt_regs *regs)
641 * Safe guard if DSP mode is already enabled or we're lacking 641 * Safe guard if DSP mode is already enabled or we're lacking
642 * the DSP altogether. 642 * the DSP altogether.
643 */ 643 */
644 if (!(cpu_data->flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) 644 if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP))
645 return 0; 645 return 0;
646 646
647 get_user(inst, ((unsigned short *) regs->pc)); 647 get_user(inst, ((unsigned short *) regs->pc));