aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/cpu/clock.c2
-rw-r--r--arch/sh/kernel/cpu/init.c27
-rw-r--r--arch/sh/kernel/cpu/irq/Makefile4
-rw-r--r--arch/sh/kernel/cpu/irq/intc.c562
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c86
-rw-r--r--arch/sh/kernel/cpu/sh2/probe.c19
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c93
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c18
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c217
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile10
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c48
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c172
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7708.c43
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7709.c145
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c224
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c200
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c210
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c178
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c54
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c253
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c4
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile6
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c4
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c38
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7770.c4
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c91
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c304
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-shx3.c234
-rw-r--r--arch/sh/kernel/cpu/sh4a/smp-shx3.c120
-rw-r--r--arch/sh/kernel/cpufreq.c3
-rw-r--r--arch/sh/kernel/early_printk.c49
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sh/kernel/head.S18
-rw-r--r--arch/sh/kernel/kgdb_stub.c53
-rw-r--r--arch/sh/kernel/process.c8
-rw-r--r--arch/sh/kernel/setup.c15
-rw-r--r--arch/sh/kernel/sh_ksyms.c18
-rw-r--r--arch/sh/kernel/signal.c10
-rw-r--r--arch/sh/kernel/smp.c307
-rw-r--r--arch/sh/kernel/syscalls.S18
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c3
-rw-r--r--arch/sh/kernel/traps.c5
-rw-r--r--arch/sh/kernel/vmlinux.lds.S10
43 files changed, 2691 insertions, 1198 deletions
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 92807ffa8e20..b5f1e23ed57c 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -83,6 +83,8 @@ static void propagate_rate(struct clk *clk)
83 continue; 83 continue;
84 if (likely(clkp->ops && clkp->ops->recalc)) 84 if (likely(clkp->ops && clkp->ops->recalc))
85 clkp->ops->recalc(clkp); 85 clkp->ops->recalc(clkp);
86 if (unlikely(clkp->flags & CLK_RATE_PROPAGATES))
87 propagate_rate(clkp);
86 } 88 }
87} 89}
88 90
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 9172e97dc26a..c217c4bf0085 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -22,6 +22,7 @@
22#include <asm/cache.h> 22#include <asm/cache.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/ubc.h> 24#include <asm/ubc.h>
25#include <asm/smp.h>
25 26
26/* 27/*
27 * Generic wrapper for command line arguments to disable on-chip 28 * Generic wrapper for command line arguments to disable on-chip
@@ -143,12 +144,15 @@ static void __init cache_init(void)
143 flags &= ~CCR_CACHE_EMODE; 144 flags &= ~CCR_CACHE_EMODE;
144#endif 145#endif
145 146
146#ifdef CONFIG_SH_WRITETHROUGH 147#if defined(CONFIG_CACHE_WRITETHROUGH)
147 /* Turn on Write-through caching */ 148 /* Write-through */
148 flags |= CCR_CACHE_WT; 149 flags |= CCR_CACHE_WT;
149#else 150#elif defined(CONFIG_CACHE_WRITEBACK)
150 /* .. or default to Write-back */ 151 /* Write-back */
151 flags |= CCR_CACHE_CB; 152 flags |= CCR_CACHE_CB;
153#else
154 /* Off */
155 flags &= ~CCR_CACHE_ENABLE;
152#endif 156#endif
153 157
154 ctrl_outl(flags, CCR); 158 ctrl_outl(flags, CCR);
@@ -213,8 +217,11 @@ static void __init dsp_init(void)
213 * Each processor family is still responsible for doing its own probing 217 * Each processor family is still responsible for doing its own probing
214 * and cache configuration in detect_cpu_and_cache_system(). 218 * and cache configuration in detect_cpu_and_cache_system().
215 */ 219 */
216asmlinkage void __init sh_cpu_init(void) 220
221asmlinkage void __cpuinit sh_cpu_init(void)
217{ 222{
223 current_thread_info()->cpu = hard_smp_processor_id();
224
218 /* First, probe the CPU */ 225 /* First, probe the CPU */
219 detect_cpu_and_cache_system(); 226 detect_cpu_and_cache_system();
220 227
@@ -224,9 +231,10 @@ asmlinkage void __init sh_cpu_init(void)
224 /* Init the cache */ 231 /* Init the cache */
225 cache_init(); 232 cache_init();
226 233
227 shm_align_mask = max_t(unsigned long, 234 if (raw_smp_processor_id() == 0)
228 current_cpu_data.dcache.way_size - 1, 235 shm_align_mask = max_t(unsigned long,
229 PAGE_SIZE - 1); 236 current_cpu_data.dcache.way_size - 1,
237 PAGE_SIZE - 1);
230 238
231 /* Disable the FPU */ 239 /* Disable the FPU */
232 if (fpu_disabled) { 240 if (fpu_disabled) {
@@ -265,6 +273,7 @@ asmlinkage void __init sh_cpu_init(void)
265 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. 273 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So ..
266 * we wake it up and hope that all is well. 274 * we wake it up and hope that all is well.
267 */ 275 */
268 ubc_wakeup(); 276 if (raw_smp_processor_id() == 0)
277 ubc_wakeup();
269 speculative_execution_init(); 278 speculative_execution_init();
270} 279}
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile
index 60bfc05cf354..8da8e178f09c 100644
--- a/arch/sh/kernel/cpu/irq/Makefile
+++ b/arch/sh/kernel/cpu/irq/Makefile
@@ -1,9 +1,7 @@
1# 1#
2# Makefile for the Linux/SuperH CPU-specifc IRQ handlers. 2# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
3# 3#
4obj-y += imask.o 4obj-y += imask.o intc.o
5 5
6obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o 6obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
7obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o 7obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
8obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o
9obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c
index 9345a7130e9e..6ac018c15e03 100644
--- a/arch/sh/kernel/cpu/irq/intc.c
+++ b/arch/sh/kernel/cpu/irq/intc.c
@@ -20,145 +20,258 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/bootmem.h>
24
25#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
26 ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
27 ((addr_e) << 16) | ((addr_d << 24)))
28
29#define _INTC_SHIFT(h) (h & 0x1f)
30#define _INTC_WIDTH(h) ((h >> 5) & 0xf)
31#define _INTC_FN(h) ((h >> 9) & 0xf)
32#define _INTC_MODE(h) ((h >> 13) & 0x7)
33#define _INTC_ADDR_E(h) ((h >> 16) & 0xff)
34#define _INTC_ADDR_D(h) ((h >> 24) & 0xff)
35
36struct intc_handle_int {
37 unsigned int irq;
38 unsigned long handle;
39};
40
41struct intc_desc_int {
42 unsigned long *reg;
43#ifdef CONFIG_SMP
44 unsigned long *smp;
45#endif
46 unsigned int nr_reg;
47 struct intc_handle_int *prio;
48 unsigned int nr_prio;
49 struct intc_handle_int *sense;
50 unsigned int nr_sense;
51 struct irq_chip chip;
52};
23 53
24#define _INTC_MK(fn, idx, bit, value) \ 54#ifdef CONFIG_SMP
25 ((fn) << 24 | ((value) << 16) | ((idx) << 8) | (bit)) 55#define IS_SMP(x) x.smp
26#define _INTC_FN(h) (h >> 24) 56#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
27#define _INTC_VALUE(h) ((h >> 16) & 0xff) 57#define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1)
28#define _INTC_IDX(h) ((h >> 8) & 0xff) 58#else
29#define _INTC_BIT(h) (h & 0xff) 59#define IS_SMP(x) 0
60#define INTC_REG(d, x, c) (d->reg[(x)])
61#define SMP_NR(d, x) 1
62#endif
30 63
31#define _INTC_PTR(desc, member, data) \ 64static unsigned int intc_prio_level[NR_IRQS]; /* for now */
32 (desc->member + _INTC_IDX(data))
33 65
34static inline struct intc_desc *get_intc_desc(unsigned int irq) 66static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
35{ 67{
36 struct irq_chip *chip = get_irq_chip(irq); 68 struct irq_chip *chip = get_irq_chip(irq);
37 return (void *)((char *)chip - offsetof(struct intc_desc, chip)); 69 return (void *)((char *)chip - offsetof(struct intc_desc_int, chip));
38} 70}
39 71
40static inline unsigned int set_field(unsigned int value, 72static inline unsigned int set_field(unsigned int value,
41 unsigned int field_value, 73 unsigned int field_value,
42 unsigned int width, 74 unsigned int handle)
43 unsigned int shift)
44{ 75{
76 unsigned int width = _INTC_WIDTH(handle);
77 unsigned int shift = _INTC_SHIFT(handle);
78
45 value &= ~(((1 << width) - 1) << shift); 79 value &= ~(((1 << width) - 1) << shift);
46 value |= field_value << shift; 80 value |= field_value << shift;
47 return value; 81 return value;
48} 82}
49 83
50static inline unsigned int set_prio_field(struct intc_desc *desc, 84static void write_8(unsigned long addr, unsigned long h, unsigned long data)
51 unsigned int value,
52 unsigned int priority,
53 unsigned int data)
54{ 85{
55 unsigned int width = _INTC_PTR(desc, prio_regs, data)->field_width; 86 ctrl_outb(set_field(0, data, h), addr);
56
57 return set_field(value, priority, width, _INTC_BIT(data));
58} 87}
59 88
60static void disable_prio_16(struct intc_desc *desc, unsigned int data) 89static void write_16(unsigned long addr, unsigned long h, unsigned long data)
61{ 90{
62 unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; 91 ctrl_outw(set_field(0, data, h), addr);
63
64 ctrl_outw(set_prio_field(desc, ctrl_inw(addr), 0, data), addr);
65} 92}
66 93
67static void enable_prio_16(struct intc_desc *desc, unsigned int data) 94static void write_32(unsigned long addr, unsigned long h, unsigned long data)
68{ 95{
69 unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; 96 ctrl_outl(set_field(0, data, h), addr);
70 unsigned int prio = _INTC_VALUE(data);
71
72 ctrl_outw(set_prio_field(desc, ctrl_inw(addr), prio, data), addr);
73} 97}
74 98
75static void disable_prio_32(struct intc_desc *desc, unsigned int data) 99static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
76{ 100{
77 unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; 101 ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
78
79 ctrl_outl(set_prio_field(desc, ctrl_inl(addr), 0, data), addr);
80} 102}
81 103
82static void enable_prio_32(struct intc_desc *desc, unsigned int data) 104static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
83{ 105{
84 unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; 106 ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
85 unsigned int prio = _INTC_VALUE(data);
86
87 ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr);
88} 107}
89 108
90static void disable_mask_8(struct intc_desc *desc, unsigned int data) 109static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
91{ 110{
92 ctrl_outb(1 << _INTC_BIT(data), 111 ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
93 _INTC_PTR(desc, mask_regs, data)->set_reg);
94} 112}
95 113
96static void enable_mask_8(struct intc_desc *desc, unsigned int data) 114enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };
115
116static void (*intc_reg_fns[])(unsigned long addr,
117 unsigned long h,
118 unsigned long data) = {
119 [REG_FN_WRITE_BASE + 0] = write_8,
120 [REG_FN_WRITE_BASE + 1] = write_16,
121 [REG_FN_WRITE_BASE + 3] = write_32,
122 [REG_FN_MODIFY_BASE + 0] = modify_8,
123 [REG_FN_MODIFY_BASE + 1] = modify_16,
124 [REG_FN_MODIFY_BASE + 3] = modify_32,
125};
126
127enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */
128 MODE_MASK_REG, /* Bit(s) set -> interrupt disabled */
129 MODE_DUAL_REG, /* Two registers, set bit to enable / disable */
130 MODE_PRIO_REG, /* Priority value written to enable interrupt */
131 MODE_PCLR_REG, /* Above plus all bits set to disable interrupt */
132};
133
134static void intc_mode_field(unsigned long addr,
135 unsigned long handle,
136 void (*fn)(unsigned long,
137 unsigned long,
138 unsigned long),
139 unsigned int irq)
97{ 140{
98 ctrl_outb(1 << _INTC_BIT(data), 141 fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1));
99 _INTC_PTR(desc, mask_regs, data)->clr_reg);
100} 142}
101 143
102static void disable_mask_32(struct intc_desc *desc, unsigned int data) 144static void intc_mode_zero(unsigned long addr,
145 unsigned long handle,
146 void (*fn)(unsigned long,
147 unsigned long,
148 unsigned long),
149 unsigned int irq)
103{ 150{
104 ctrl_outl(1 << _INTC_BIT(data), 151 fn(addr, handle, 0);
105 _INTC_PTR(desc, mask_regs, data)->set_reg);
106} 152}
107 153
108static void enable_mask_32(struct intc_desc *desc, unsigned int data) 154static void intc_mode_prio(unsigned long addr,
155 unsigned long handle,
156 void (*fn)(unsigned long,
157 unsigned long,
158 unsigned long),
159 unsigned int irq)
109{ 160{
110 ctrl_outl(1 << _INTC_BIT(data), 161 fn(addr, handle, intc_prio_level[irq]);
111 _INTC_PTR(desc, mask_regs, data)->clr_reg);
112} 162}
113 163
114enum { REG_FN_ERROR=0, 164static void (*intc_enable_fns[])(unsigned long addr,
115 REG_FN_MASK_8, REG_FN_MASK_32, 165 unsigned long handle,
116 REG_FN_PRIO_16, REG_FN_PRIO_32 }; 166 void (*fn)(unsigned long,
117 167 unsigned long,
118static struct { 168 unsigned long),
119 void (*enable)(struct intc_desc *, unsigned int); 169 unsigned int irq) = {
120 void (*disable)(struct intc_desc *, unsigned int); 170 [MODE_ENABLE_REG] = intc_mode_field,
121} intc_reg_fns[] = { 171 [MODE_MASK_REG] = intc_mode_zero,
122 [REG_FN_MASK_8] = { enable_mask_8, disable_mask_8 }, 172 [MODE_DUAL_REG] = intc_mode_field,
123 [REG_FN_MASK_32] = { enable_mask_32, disable_mask_32 }, 173 [MODE_PRIO_REG] = intc_mode_prio,
124 [REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 }, 174 [MODE_PCLR_REG] = intc_mode_prio,
125 [REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 },
126}; 175};
127 176
128static void intc_enable(unsigned int irq) 177static void (*intc_disable_fns[])(unsigned long addr,
178 unsigned long handle,
179 void (*fn)(unsigned long,
180 unsigned long,
181 unsigned long),
182 unsigned int irq) = {
183 [MODE_ENABLE_REG] = intc_mode_zero,
184 [MODE_MASK_REG] = intc_mode_field,
185 [MODE_DUAL_REG] = intc_mode_field,
186 [MODE_PRIO_REG] = intc_mode_zero,
187 [MODE_PCLR_REG] = intc_mode_field,
188};
189
190static inline void _intc_enable(unsigned int irq, unsigned long handle)
129{ 191{
130 struct intc_desc *desc = get_intc_desc(irq); 192 struct intc_desc_int *d = get_intc_desc(irq);
131 unsigned int data = (unsigned int) get_irq_chip_data(irq); 193 unsigned long addr;
194 unsigned int cpu;
195
196 for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
197 addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
198 intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
199 [_INTC_FN(handle)], irq);
200 }
201}
132 202
133 intc_reg_fns[_INTC_FN(data)].enable(desc, data); 203static void intc_enable(unsigned int irq)
204{
205 _intc_enable(irq, (unsigned long)get_irq_chip_data(irq));
134} 206}
135 207
136static void intc_disable(unsigned int irq) 208static void intc_disable(unsigned int irq)
137{ 209{
138 struct intc_desc *desc = get_intc_desc(irq); 210 struct intc_desc_int *d = get_intc_desc(irq);
139 unsigned int data = (unsigned int) get_irq_chip_data(irq); 211 unsigned long handle = (unsigned long) get_irq_chip_data(irq);
140 212 unsigned long addr;
141 intc_reg_fns[_INTC_FN(data)].disable(desc, data); 213 unsigned int cpu;
214
215 for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
216 addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
217 intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
218 [_INTC_FN(handle)], irq);
219 }
142} 220}
143 221
144static void set_sense_16(struct intc_desc *desc, unsigned int data) 222static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
223 unsigned int nr_hp,
224 unsigned int irq)
145{ 225{
146 unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; 226 int i;
147 unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; 227
148 unsigned int bit = _INTC_BIT(data); 228 /* this doesn't scale well, but...
149 unsigned int value = _INTC_VALUE(data); 229 *
230 * this function should only be used for cerain uncommon
231 * operations such as intc_set_priority() and intc_set_sense()
232 * and in those rare cases performance doesn't matter that much.
233 * keeping the memory footprint low is more important.
234 *
235 * one rather simple way to speed this up and still keep the
236 * memory footprint down is to make sure the array is sorted
237 * and then perform a bisect to lookup the irq.
238 */
150 239
151 ctrl_outw(set_field(ctrl_inw(addr), value, width, bit), addr); 240 for (i = 0; i < nr_hp; i++) {
241 if ((hp + i)->irq != irq)
242 continue;
243
244 return hp + i;
245 }
246
247 return NULL;
152} 248}
153 249
154static void set_sense_32(struct intc_desc *desc, unsigned int data) 250int intc_set_priority(unsigned int irq, unsigned int prio)
155{ 251{
156 unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; 252 struct intc_desc_int *d = get_intc_desc(irq);
157 unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; 253 struct intc_handle_int *ihp;
158 unsigned int bit = _INTC_BIT(data); 254
159 unsigned int value = _INTC_VALUE(data); 255 if (!intc_prio_level[irq] || prio <= 1)
256 return -EINVAL;
257
258 ihp = intc_find_irq(d->prio, d->nr_prio, irq);
259 if (ihp) {
260 if (prio >= (1 << _INTC_WIDTH(ihp->handle)))
261 return -EINVAL;
160 262
161 ctrl_outl(set_field(ctrl_inl(addr), value, width, bit), addr); 263 intc_prio_level[irq] = prio;
264
265 /*
266 * only set secondary masking method directly
267 * primary masking method is using intc_prio_level[irq]
268 * priority level will be set during next enable()
269 */
270
271 if (_INTC_FN(ihp->handle) != REG_FN_ERR)
272 _intc_enable(irq, ihp->handle);
273 }
274 return 0;
162} 275}
163 276
164#define VALID(x) (x | 0x80) 277#define VALID(x) (x | 0x80)
@@ -172,79 +285,38 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
172 285
173static int intc_set_sense(unsigned int irq, unsigned int type) 286static int intc_set_sense(unsigned int irq, unsigned int type)
174{ 287{
175 struct intc_desc *desc = get_intc_desc(irq); 288 struct intc_desc_int *d = get_intc_desc(irq);
176 unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; 289 unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK];
177 unsigned int i, j, data, bit; 290 struct intc_handle_int *ihp;
178 intc_enum enum_id = 0; 291 unsigned long addr;
179
180 for (i = 0; i < desc->nr_vectors; i++) {
181 struct intc_vect *vect = desc->vectors + i;
182
183 if (evt2irq(vect->vect) != irq)
184 continue;
185 292
186 enum_id = vect->enum_id; 293 if (!value)
187 break;
188 }
189
190 if (!enum_id || !value)
191 return -EINVAL; 294 return -EINVAL;
192 295
193 value ^= VALID(0); 296 ihp = intc_find_irq(d->sense, d->nr_sense, irq);
194 297 if (ihp) {
195 for (i = 0; i < desc->nr_sense_regs; i++) { 298 addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0);
196 struct intc_sense_reg *sr = desc->sense_regs + i; 299 intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value);
197
198 for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
199 if (sr->enum_ids[j] != enum_id)
200 continue;
201
202 bit = sr->reg_width - ((j + 1) * sr->field_width);
203 data = _INTC_MK(0, i, bit, value);
204
205 switch(sr->reg_width) {
206 case 16:
207 set_sense_16(desc, data);
208 break;
209 case 32:
210 set_sense_32(desc, data);
211 break;
212 }
213
214 return 0;
215 }
216 } 300 }
217 301 return 0;
218 return -EINVAL;
219} 302}
220 303
221static unsigned int __init intc_find_mask_handler(unsigned int width) 304static unsigned int __init intc_get_reg(struct intc_desc_int *d,
305 unsigned long address)
222{ 306{
223 switch (width) { 307 unsigned int k;
224 case 8:
225 return REG_FN_MASK_8;
226 case 32:
227 return REG_FN_MASK_32;
228 }
229 308
230 BUG(); 309 for (k = 0; k < d->nr_reg; k++) {
231 return REG_FN_ERROR; 310 if (d->reg[k] == address)
232} 311 return k;
233
234static unsigned int __init intc_find_prio_handler(unsigned int width)
235{
236 switch (width) {
237 case 16:
238 return REG_FN_PRIO_16;
239 case 32:
240 return REG_FN_PRIO_32;
241 } 312 }
242 313
243 BUG(); 314 BUG();
244 return REG_FN_ERROR; 315 return 0;
245} 316}
246 317
247static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) 318static intc_enum __init intc_grp_id(struct intc_desc *desc,
319 intc_enum enum_id)
248{ 320{
249 struct intc_group *g = desc->groups; 321 struct intc_group *g = desc->groups;
250 unsigned int i, j; 322 unsigned int i, j;
@@ -289,10 +361,12 @@ static unsigned int __init intc_prio_value(struct intc_desc *desc,
289} 361}
290 362
291static unsigned int __init intc_mask_data(struct intc_desc *desc, 363static unsigned int __init intc_mask_data(struct intc_desc *desc,
364 struct intc_desc_int *d,
292 intc_enum enum_id, int do_grps) 365 intc_enum enum_id, int do_grps)
293{ 366{
294 struct intc_mask_reg *mr = desc->mask_regs; 367 struct intc_mask_reg *mr = desc->mask_regs;
295 unsigned int i, j, fn; 368 unsigned int i, j, fn, mode;
369 unsigned long reg_e, reg_d;
296 370
297 for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) { 371 for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) {
298 mr = desc->mask_regs + i; 372 mr = desc->mask_regs + i;
@@ -301,25 +375,46 @@ static unsigned int __init intc_mask_data(struct intc_desc *desc,
301 if (mr->enum_ids[j] != enum_id) 375 if (mr->enum_ids[j] != enum_id)
302 continue; 376 continue;
303 377
304 fn = intc_find_mask_handler(mr->reg_width); 378 if (mr->set_reg && mr->clr_reg) {
305 if (fn == REG_FN_ERROR) 379 fn = REG_FN_WRITE_BASE;
306 return 0; 380 mode = MODE_DUAL_REG;
381 reg_e = mr->clr_reg;
382 reg_d = mr->set_reg;
383 } else {
384 fn = REG_FN_MODIFY_BASE;
385 if (mr->set_reg) {
386 mode = MODE_ENABLE_REG;
387 reg_e = mr->set_reg;
388 reg_d = mr->set_reg;
389 } else {
390 mode = MODE_MASK_REG;
391 reg_e = mr->clr_reg;
392 reg_d = mr->clr_reg;
393 }
394 }
307 395
308 return _INTC_MK(fn, i, (mr->reg_width - 1) - j, 0); 396 fn += (mr->reg_width >> 3) - 1;
397 return _INTC_MK(fn, mode,
398 intc_get_reg(d, reg_e),
399 intc_get_reg(d, reg_d),
400 1,
401 (mr->reg_width - 1) - j);
309 } 402 }
310 } 403 }
311 404
312 if (do_grps) 405 if (do_grps)
313 return intc_mask_data(desc, intc_grp_id(desc, enum_id), 0); 406 return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0);
314 407
315 return 0; 408 return 0;
316} 409}
317 410
318static unsigned int __init intc_prio_data(struct intc_desc *desc, 411static unsigned int __init intc_prio_data(struct intc_desc *desc,
412 struct intc_desc_int *d,
319 intc_enum enum_id, int do_grps) 413 intc_enum enum_id, int do_grps)
320{ 414{
321 struct intc_prio_reg *pr = desc->prio_regs; 415 struct intc_prio_reg *pr = desc->prio_regs;
322 unsigned int i, j, fn, bit, prio; 416 unsigned int i, j, fn, mode, bit;
417 unsigned long reg_e, reg_d;
323 418
324 for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) { 419 for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) {
325 pr = desc->prio_regs + i; 420 pr = desc->prio_regs + i;
@@ -328,28 +423,72 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
328 if (pr->enum_ids[j] != enum_id) 423 if (pr->enum_ids[j] != enum_id)
329 continue; 424 continue;
330 425
331 fn = intc_find_prio_handler(pr->reg_width); 426 if (pr->set_reg && pr->clr_reg) {
332 if (fn == REG_FN_ERROR) 427 fn = REG_FN_WRITE_BASE;
333 return 0; 428 mode = MODE_PCLR_REG;
429 reg_e = pr->set_reg;
430 reg_d = pr->clr_reg;
431 } else {
432 fn = REG_FN_MODIFY_BASE;
433 mode = MODE_PRIO_REG;
434 if (!pr->set_reg)
435 BUG();
436 reg_e = pr->set_reg;
437 reg_d = pr->set_reg;
438 }
334 439
335 prio = intc_prio_value(desc, enum_id, 1); 440 fn += (pr->reg_width >> 3) - 1;
336 bit = pr->reg_width - ((j + 1) * pr->field_width); 441 bit = pr->reg_width - ((j + 1) * pr->field_width);
337 442
338 BUG_ON(bit < 0); 443 BUG_ON(bit < 0);
339 444
340 return _INTC_MK(fn, i, bit, prio); 445 return _INTC_MK(fn, mode,
446 intc_get_reg(d, reg_e),
447 intc_get_reg(d, reg_d),
448 pr->field_width, bit);
341 } 449 }
342 } 450 }
343 451
344 if (do_grps) 452 if (do_grps)
345 return intc_prio_data(desc, intc_grp_id(desc, enum_id), 0); 453 return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0);
346 454
347 return 0; 455 return 0;
348} 456}
349 457
350static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, 458static unsigned int __init intc_sense_data(struct intc_desc *desc,
459 struct intc_desc_int *d,
460 intc_enum enum_id)
461{
462 struct intc_sense_reg *sr = desc->sense_regs;
463 unsigned int i, j, fn, bit;
464
465 for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) {
466 sr = desc->sense_regs + i;
467
468 for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
469 if (sr->enum_ids[j] != enum_id)
470 continue;
471
472 fn = REG_FN_MODIFY_BASE;
473 fn += (sr->reg_width >> 3) - 1;
474 bit = sr->reg_width - ((j + 1) * sr->field_width);
475
476 BUG_ON(bit < 0);
477
478 return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg),
479 0, sr->field_width, bit);
480 }
481 }
482
483 return 0;
484}
485
486static void __init intc_register_irq(struct intc_desc *desc,
487 struct intc_desc_int *d,
488 intc_enum enum_id,
351 unsigned int irq) 489 unsigned int irq)
352{ 490{
491 struct intc_handle_int *hp;
353 unsigned int data[2], primary; 492 unsigned int data[2], primary;
354 493
355 /* Prefer single interrupt source bitmap over other combinations: 494 /* Prefer single interrupt source bitmap over other combinations:
@@ -359,15 +498,15 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id,
359 * 4. priority, multiple interrupt sources (groups) 498 * 4. priority, multiple interrupt sources (groups)
360 */ 499 */
361 500
362 data[0] = intc_mask_data(desc, enum_id, 0); 501 data[0] = intc_mask_data(desc, d, enum_id, 0);
363 data[1] = intc_prio_data(desc, enum_id, 0); 502 data[1] = intc_prio_data(desc, d, enum_id, 0);
364 503
365 primary = 0; 504 primary = 0;
366 if (!data[0] && data[1]) 505 if (!data[0] && data[1])
367 primary = 1; 506 primary = 1;
368 507
369 data[0] = data[0] ? data[0] : intc_mask_data(desc, enum_id, 1); 508 data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1);
370 data[1] = data[1] ? data[1] : intc_prio_data(desc, enum_id, 1); 509 data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1);
371 510
372 if (!data[primary]) 511 if (!data[primary])
373 primary ^= 1; 512 primary ^= 1;
@@ -375,31 +514,118 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id,
375 BUG_ON(!data[primary]); /* must have primary masking method */ 514 BUG_ON(!data[primary]); /* must have primary masking method */
376 515
377 disable_irq_nosync(irq); 516 disable_irq_nosync(irq);
378 set_irq_chip_and_handler_name(irq, &desc->chip, 517 set_irq_chip_and_handler_name(irq, &d->chip,
379 handle_level_irq, "level"); 518 handle_level_irq, "level");
380 set_irq_chip_data(irq, (void *)data[primary]); 519 set_irq_chip_data(irq, (void *)data[primary]);
381 520
521 /* record the desired priority level */
522 intc_prio_level[irq] = intc_prio_value(desc, enum_id, 1);
523
382 /* enable secondary masking method if present */ 524 /* enable secondary masking method if present */
383 if (data[!primary]) 525 if (data[!primary])
384 intc_reg_fns[_INTC_FN(data[!primary])].enable(desc, 526 _intc_enable(irq, data[!primary]);
385 data[!primary]); 527
528 /* add irq to d->prio list if priority is available */
529 if (data[1]) {
530 hp = d->prio + d->nr_prio;
531 hp->irq = irq;
532 hp->handle = data[1];
533
534 if (primary) {
535 /*
536 * only secondary priority should access registers, so
537 * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority()
538 */
539
540 hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0);
541 hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0);
542 }
543 d->nr_prio++;
544 }
545
546 /* add irq to d->sense list if sense is available */
547 data[0] = intc_sense_data(desc, d, enum_id);
548 if (data[0]) {
549 (d->sense + d->nr_sense)->irq = irq;
550 (d->sense + d->nr_sense)->handle = data[0];
551 d->nr_sense++;
552 }
386 553
387 /* irq should be disabled by default */ 554 /* irq should be disabled by default */
388 desc->chip.mask(irq); 555 d->chip.mask(irq);
389} 556}
390 557
558static unsigned int __init save_reg(struct intc_desc_int *d,
559 unsigned int cnt,
560 unsigned long value,
561 unsigned int smp)
562{
563 if (value) {
564 d->reg[cnt] = value;
565#ifdef CONFIG_SMP
566 d->smp[cnt] = smp;
567#endif
568 return 1;
569 }
570
571 return 0;
572}
573
574
391void __init register_intc_controller(struct intc_desc *desc) 575void __init register_intc_controller(struct intc_desc *desc)
392{ 576{
393 unsigned int i; 577 unsigned int i, k, smp;
578 struct intc_desc_int *d;
579
580 d = alloc_bootmem(sizeof(*d));
581
582 d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
583 d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
584 d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
585
586 d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
587#ifdef CONFIG_SMP
588 d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp));
589#endif
590 k = 0;
591
592 if (desc->mask_regs) {
593 for (i = 0; i < desc->nr_mask_regs; i++) {
594 smp = IS_SMP(desc->mask_regs[i]);
595 k += save_reg(d, k, desc->mask_regs[i].set_reg, smp);
596 k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp);
597 }
598 }
599
600 if (desc->prio_regs) {
601 d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio));
602
603 for (i = 0; i < desc->nr_prio_regs; i++) {
604 smp = IS_SMP(desc->prio_regs[i]);
605 k += save_reg(d, k, desc->prio_regs[i].set_reg, smp);
606 k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp);
607 }
608 }
609
610 if (desc->sense_regs) {
611 d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense));
612
613 for (i = 0; i < desc->nr_sense_regs; i++) {
614 k += save_reg(d, k, desc->sense_regs[i].reg, 0);
615 }
616 }
617
618 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
394 619
395 desc->chip.mask = intc_disable; 620 d->chip.name = desc->name;
396 desc->chip.unmask = intc_enable; 621 d->chip.mask = intc_disable;
397 desc->chip.mask_ack = intc_disable; 622 d->chip.unmask = intc_enable;
398 desc->chip.set_type = intc_set_sense; 623 d->chip.mask_ack = intc_disable;
624 d->chip.set_type = intc_set_sense;
399 625
400 for (i = 0; i < desc->nr_vectors; i++) { 626 for (i = 0; i < desc->nr_vectors; i++) {
401 struct intc_vect *vect = desc->vectors + i; 627 struct intc_vect *vect = desc->vectors + i;
402 628
403 intc_register_irq(desc, vect->enum_id, evt2irq(vect->vect)); 629 intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
404 } 630 }
405} 631}
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
deleted file mode 100644
index cc5221390e09..000000000000
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2 * Interrupt handling for INTC2-based IRQ.
3 *
4 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
5 * Copyright (C) 2005, 2006 Paul Mundt (lethal@linux-sh.org)
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 * These are the "new Hitachi style" interrupts, as present on the
11 * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
12 */
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <asm/smp.h>
17
18static inline struct intc2_desc *get_intc2_desc(unsigned int irq)
19{
20 struct irq_chip *chip = get_irq_chip(irq);
21 return (void *)((char *)chip - offsetof(struct intc2_desc, chip));
22}
23
24static void disable_intc2_irq(unsigned int irq)
25{
26 struct intc2_data *p = get_irq_chip_data(irq);
27 struct intc2_desc *d = get_intc2_desc(irq);
28
29 ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset +
30 (hard_smp_processor_id() * 4));
31}
32
33static void enable_intc2_irq(unsigned int irq)
34{
35 struct intc2_data *p = get_irq_chip_data(irq);
36 struct intc2_desc *d = get_intc2_desc(irq);
37
38 ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset +
39 (hard_smp_processor_id() * 4));
40}
41
42/*
43 * Setup an INTC2 style interrupt.
44 * NOTE: Unlike IPR interrupts, parameters are not shifted by this code,
45 * allowing the use of the numbers straight out of the datasheet.
46 * For example:
47 * PIO1 which is INTPRI00[19,16] and INTMSK00[13]
48 * would be: ^ ^ ^ ^
49 * | | | |
50 * { 84, 0, 16, 0, 13 },
51 *
52 * in the intc2_data table.
53 */
54void register_intc2_controller(struct intc2_desc *desc)
55{
56 int i;
57
58 desc->chip.mask = disable_intc2_irq;
59 desc->chip.unmask = enable_intc2_irq;
60 desc->chip.mask_ack = disable_intc2_irq;
61
62 for (i = 0; i < desc->nr_irqs; i++) {
63 unsigned long ipr, flags;
64 struct intc2_data *p = desc->intc2_data + i;
65
66 disable_irq_nosync(p->irq);
67
68 if (desc->prio_base) {
69 /* Set the priority level */
70 local_irq_save(flags);
71
72 ipr = ctrl_inl(desc->prio_base + p->ipr_offset);
73 ipr &= ~(0xf << p->ipr_shift);
74 ipr |= p->priority << p->ipr_shift;
75 ctrl_outl(ipr, desc->prio_base + p->ipr_offset);
76
77 local_irq_restore(flags);
78 }
79
80 set_irq_chip_and_handler_name(p->irq, &desc->chip,
81 handle_level_irq, "level");
82 set_irq_chip_data(p->irq, p);
83
84 disable_intc2_irq(p->irq);
85 }
86}
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
index abbf17427e52..5916d9096b99 100644
--- a/arch/sh/kernel/cpu/sh2/probe.c
+++ b/arch/sh/kernel/cpu/sh2/probe.c
@@ -10,26 +10,25 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/smp.h>
14#include <asm/processor.h> 13#include <asm/processor.h>
15#include <asm/cache.h> 14#include <asm/cache.h>
16 15
17int __init detect_cpu_and_cache_system(void) 16int __init detect_cpu_and_cache_system(void)
18{ 17{
19#if defined(CONFIG_CPU_SUBTYPE_SH7619) 18#if defined(CONFIG_CPU_SUBTYPE_SH7619)
20 current_cpu_data.type = CPU_SH7619; 19 boot_cpu_data.type = CPU_SH7619;
21 current_cpu_data.dcache.ways = 4; 20 boot_cpu_data.dcache.ways = 4;
22 current_cpu_data.dcache.way_incr = (1<<12); 21 boot_cpu_data.dcache.way_incr = (1<<12);
23 current_cpu_data.dcache.sets = 256; 22 boot_cpu_data.dcache.sets = 256;
24 current_cpu_data.dcache.entry_shift = 4; 23 boot_cpu_data.dcache.entry_shift = 4;
25 current_cpu_data.dcache.linesz = L1_CACHE_BYTES; 24 boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
26 current_cpu_data.dcache.flags = 0; 25 boot_cpu_data.dcache.flags = 0;
27#endif 26#endif
28 /* 27 /*
29 * SH-2 doesn't have separate caches 28 * SH-2 doesn't have separate caches
30 */ 29 */
31 current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; 30 boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
32 current_cpu_data.icache = current_cpu_data.dcache; 31 boot_cpu_data.icache = boot_cpu_data.dcache;
33 32
34 return 0; 33 return 0;
35} 34}
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index a979b981e6a3..ec6adc3f306f 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -12,6 +12,61 @@
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <asm/sci.h> 13#include <asm/sci.h>
14 14
15enum {
16 UNUSED = 0,
17
18 /* interrupt sources */
19 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
20 WDT, EDMAC, CMT0, CMT1,
21 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
22 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
23 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
24 HIF_HIFI, HIF_HIFBI,
25 DMAC0, DMAC1, DMAC2, DMAC3,
26 SIOF,
27
28 /* interrupt groups */
29 SCIF0, SCIF1, SCIF2,
30};
31
32static struct intc_vect vectors[] __initdata = {
33 INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
34 INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
35 INTC_IRQ(IRQ4, 80), INTC_IRQ(IRQ5, 81),
36 INTC_IRQ(IRQ6, 82), INTC_IRQ(IRQ7, 83),
37 INTC_IRQ(WDT, 84), INTC_IRQ(EDMAC, 85),
38 INTC_IRQ(CMT0, 86), INTC_IRQ(CMT1, 87),
39 INTC_IRQ(SCIF0_ERI, 88), INTC_IRQ(SCIF0_RXI, 89),
40 INTC_IRQ(SCIF0_BRI, 90), INTC_IRQ(SCIF0_TXI, 91),
41 INTC_IRQ(SCIF1_ERI, 92), INTC_IRQ(SCIF1_RXI, 93),
42 INTC_IRQ(SCIF1_BRI, 94), INTC_IRQ(SCIF1_TXI, 95),
43 INTC_IRQ(SCIF2_ERI, 96), INTC_IRQ(SCIF2_RXI, 97),
44 INTC_IRQ(SCIF2_BRI, 98), INTC_IRQ(SCIF2_TXI, 99),
45 INTC_IRQ(HIF_HIFI, 100), INTC_IRQ(HIF_HIFBI, 101),
46 INTC_IRQ(DMAC0, 104), INTC_IRQ(DMAC1, 105),
47 INTC_IRQ(DMAC2, 106), INTC_IRQ(DMAC3, 107),
48 INTC_IRQ(SIOF, 108),
49};
50
51static struct intc_group groups[] __initdata = {
52 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
53 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
54 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
55};
56
57static struct intc_prio_reg prio_registers[] __initdata = {
58 { 0xf8140006, 0, 16, 4, /* IPRA */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
59 { 0xf8140008, 0, 16, 4, /* IPRB */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
60 { 0xf8080000, 0, 16, 4, /* IPRC */ { WDT, EDMAC, CMT0, CMT1 } },
61 { 0xf8080002, 0, 16, 4, /* IPRD */ { SCIF0, SCIF1, SCIF2 } },
62 { 0xf8080004, 0, 16, 4, /* IPRE */ { HIF_HIFI, HIF_HIFBI } },
63 { 0xf8080006, 0, 16, 4, /* IPRF */ { DMAC0, DMAC1, DMAC2, DMAC3 } },
64 { 0xf8080008, 0, 16, 4, /* IPRG */ { SIOF } },
65};
66
67static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups,
68 NULL, NULL, prio_registers, NULL);
69
15static struct plat_sci_port sci_platform_data[] = { 70static struct plat_sci_port sci_platform_data[] = {
16 { 71 {
17 .mapbase = 0xf8400000, 72 .mapbase = 0xf8400000,
@@ -52,43 +107,7 @@ static int __init sh7619_devices_setup(void)
52} 107}
53__initcall(sh7619_devices_setup); 108__initcall(sh7619_devices_setup);
54 109
55static struct ipr_data ipr_irq_table[] = {
56 { 86, 0, 4, 2 }, /* CMI0 */
57 { 88, 1, 12, 3 }, /* SCIF0_ERI */
58 { 89, 1, 12, 3 }, /* SCIF0_RXI */
59 { 90, 1, 12, 3 }, /* SCIF0_BRI */
60 { 91, 1, 12, 3 }, /* SCIF0_TXI */
61 { 92, 1, 8, 3 }, /* SCIF1_ERI */
62 { 93, 1, 8, 3 }, /* SCIF1_RXI */
63 { 94, 1, 8, 3 }, /* SCIF1_BRI */
64 { 95, 1, 8, 3 }, /* SCIF1_TXI */
65 { 96, 1, 4, 3 }, /* SCIF2_ERI */
66 { 97, 1, 4, 3 }, /* SCIF2_RXI */
67 { 98, 1, 4, 3 }, /* SCIF2_BRI */
68 { 99, 1, 4, 3 }, /* SCIF2_TXI */
69};
70
71static unsigned long ipr_offsets[] = {
72 0xf8080000, /* IPRC */
73 0xf8080002, /* IPRD */
74 0xf8080004, /* IPRE */
75 0xf8080006, /* IPRF */
76 0xf8080008, /* IPRG */
77};
78
79static struct ipr_desc ipr_irq_desc = {
80 .ipr_offsets = ipr_offsets,
81 .nr_offsets = ARRAY_SIZE(ipr_offsets),
82
83 .ipr_data = ipr_irq_table,
84 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
85
86 .chip = {
87 .name = "IPR-sh7619",
88 },
89};
90
91void __init plat_irq_setup(void) 110void __init plat_irq_setup(void)
92{ 111{
93 register_ipr_controller(&ipr_irq_desc); 112 register_intc_controller(&intc_desc);
94} 113}
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index f455c3509789..6d02465704b9 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -17,15 +17,15 @@
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 current_cpu_data.type = CPU_SH7206; 20 boot_cpu_data.type = CPU_SH7206;
21 current_cpu_data.flags |= CPU_HAS_OP32; 21 boot_cpu_data.flags |= CPU_HAS_OP32;
22 22
23 current_cpu_data.dcache.ways = 4; 23 boot_cpu_data.dcache.ways = 4;
24 current_cpu_data.dcache.way_incr = (1 << 11); 24 boot_cpu_data.dcache.way_incr = (1 << 11);
25 current_cpu_data.dcache.sets = 128; 25 boot_cpu_data.dcache.sets = 128;
26 current_cpu_data.dcache.entry_shift = 4; 26 boot_cpu_data.dcache.entry_shift = 4;
27 current_cpu_data.dcache.linesz = L1_CACHE_BYTES; 27 boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
28 current_cpu_data.dcache.flags = 0; 28 boot_cpu_data.dcache.flags = 0;
29 29
30 /* 30 /*
31 * The icache is the same as the dcache as far as this setup is 31 * The icache is the same as the dcache as far as this setup is
@@ -33,7 +33,7 @@ int __init detect_cpu_and_cache_system(void)
33 * lacks the U bit that the dcache has, none of this has any bearing 33 * lacks the U bit that the dcache has, none of this has any bearing
34 * on the cache info. 34 * on the cache info.
35 */ 35 */
36 current_cpu_data.icache = current_cpu_data.dcache; 36 boot_cpu_data.icache = boot_cpu_data.dcache;
37 37
38 return 0; 38 return 0;
39} 39}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index deab16500167..bd745aa87222 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -12,27 +12,184 @@
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <asm/sci.h> 13#include <asm/sci.h>
14 14
15enum {
16 UNUSED = 0,
17
18 /* interrupt sources */
19 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
20 PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
21 ADC_ADI0, ADC_ADI1,
22 DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI,
23 DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI,
24 DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI,
25 DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI,
26 CMT0, CMT1, BSC, WDT,
27 MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
28 MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
29 MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
30 MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
31 MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
32 MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
33 MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
34 POE2_OEI1, POE2_OEI2,
35 MTU2S_TGI3A, MTU2S_TGI3B, MTU2S_TGI3C, MTU2S_TGI3D, MTU2S_TCI3V,
36 MTU2S_TGI4A, MTU2S_TGI4B, MTU2S_TGI4C, MTU2S_TGI4D, MTU2S_TCI4V,
37 MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W,
38 POE2_OEI3,
39 IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI,
40 SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
41 SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
42 SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
43 SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
44
45 /* interrupt groups */
46 PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
47 MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
48 MTU3_ABCD, MTU4_ABCD, MTU5, POE2_12, MTU3S_ABCD, MTU4S_ABCD, MTU5S,
49 IIC3, SCIF0, SCIF1, SCIF2, SCIF3,
50};
51
52static struct intc_vect vectors[] __initdata = {
53 INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
54 INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
55 INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
56 INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
57 INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
58 INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
59 INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
60 INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
61 INTC_IRQ(ADC_ADI0, 92), INTC_IRQ(ADC_ADI1, 96),
62 INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109),
63 INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113),
64 INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117),
65 INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121),
66 INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125),
67 INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129),
68 INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133),
69 INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137),
70 INTC_IRQ(CMT0, 140), INTC_IRQ(CMT1, 144),
71 INTC_IRQ(BSC, 148), INTC_IRQ(WDT, 152),
72 INTC_IRQ(MTU2_TGI0A, 156), INTC_IRQ(MTU2_TGI0B, 157),
73 INTC_IRQ(MTU2_TGI0C, 158), INTC_IRQ(MTU2_TGI0D, 159),
74 INTC_IRQ(MTU2_TCI0V, 160),
75 INTC_IRQ(MTU2_TGI0E, 161), INTC_IRQ(MTU2_TGI0F, 162),
76 INTC_IRQ(MTU2_TGI1A, 164), INTC_IRQ(MTU2_TGI1B, 165),
77 INTC_IRQ(MTU2_TCI1V, 168), INTC_IRQ(MTU2_TCI1U, 169),
78 INTC_IRQ(MTU2_TGI2A, 172), INTC_IRQ(MTU2_TGI2B, 173),
79 INTC_IRQ(MTU2_TCI2V, 176), INTC_IRQ(MTU2_TCI2U, 177),
80 INTC_IRQ(MTU2_TGI3A, 180), INTC_IRQ(MTU2_TGI3B, 181),
81 INTC_IRQ(MTU2_TGI3C, 182), INTC_IRQ(MTU2_TGI3D, 183),
82 INTC_IRQ(MTU2_TCI3V, 184),
83 INTC_IRQ(MTU2_TGI4A, 188), INTC_IRQ(MTU2_TGI4B, 189),
84 INTC_IRQ(MTU2_TGI4C, 190), INTC_IRQ(MTU2_TGI4D, 191),
85 INTC_IRQ(MTU2_TCI4V, 192),
86 INTC_IRQ(MTU2_TGI5U, 196), INTC_IRQ(MTU2_TGI5V, 197),
87 INTC_IRQ(MTU2_TGI5W, 198),
88 INTC_IRQ(POE2_OEI1, 200), INTC_IRQ(POE2_OEI2, 201),
89 INTC_IRQ(MTU2S_TGI3A, 204), INTC_IRQ(MTU2S_TGI3B, 205),
90 INTC_IRQ(MTU2S_TGI3C, 206), INTC_IRQ(MTU2S_TGI3D, 207),
91 INTC_IRQ(MTU2S_TCI3V, 208),
92 INTC_IRQ(MTU2S_TGI4A, 212), INTC_IRQ(MTU2S_TGI4B, 213),
93 INTC_IRQ(MTU2S_TGI4C, 214), INTC_IRQ(MTU2S_TGI4D, 215),
94 INTC_IRQ(MTU2S_TCI4V, 216),
95 INTC_IRQ(MTU2S_TGI5U, 220), INTC_IRQ(MTU2S_TGI5V, 221),
96 INTC_IRQ(MTU2S_TGI5W, 222),
97 INTC_IRQ(POE2_OEI3, 224),
98 INTC_IRQ(IIC3_STPI, 228), INTC_IRQ(IIC3_NAKI, 229),
99 INTC_IRQ(IIC3_RXI, 230), INTC_IRQ(IIC3_TXI, 231),
100 INTC_IRQ(IIC3_TEI, 232),
101 INTC_IRQ(SCIF0_BRI, 240), INTC_IRQ(SCIF0_ERI, 241),
102 INTC_IRQ(SCIF0_RXI, 242), INTC_IRQ(SCIF0_TXI, 243),
103 INTC_IRQ(SCIF1_BRI, 244), INTC_IRQ(SCIF1_ERI, 245),
104 INTC_IRQ(SCIF1_RXI, 246), INTC_IRQ(SCIF1_TXI, 247),
105 INTC_IRQ(SCIF2_BRI, 248), INTC_IRQ(SCIF2_ERI, 249),
106 INTC_IRQ(SCIF2_RXI, 250), INTC_IRQ(SCIF2_TXI, 251),
107 INTC_IRQ(SCIF3_BRI, 252), INTC_IRQ(SCIF3_ERI, 253),
108 INTC_IRQ(SCIF3_RXI, 254), INTC_IRQ(SCIF3_TXI, 255),
109};
110
111static struct intc_group groups[] __initdata = {
112 INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
113 PINT4, PINT5, PINT6, PINT7),
114 INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI),
115 INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI),
116 INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI),
117 INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI),
118 INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI),
119 INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI),
120 INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI),
121 INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI),
122 INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
123 INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
124 INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B),
125 INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U),
126 INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B),
127 INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U),
128 INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
129 INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
130 INTC_GROUP(MTU5, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
131 INTC_GROUP(POE2_12, POE2_OEI1, POE2_OEI2),
132 INTC_GROUP(MTU3S_ABCD, MTU2S_TGI3A, MTU2S_TGI3B,
133 MTU2S_TGI3C, MTU2S_TGI3D),
134 INTC_GROUP(MTU4S_ABCD, MTU2S_TGI4A, MTU2S_TGI4B,
135 MTU2S_TGI4C, MTU2S_TGI4D),
136 INTC_GROUP(MTU5S, MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W),
137 INTC_GROUP(IIC3, IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI),
138 INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
139 INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
140 INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
141 INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
142};
143
144static struct intc_prio_reg prio_registers[] __initdata = {
145 { 0xfffe0818, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
146 { 0xfffe081a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
147 { 0xfffe0820, 0, 16, 4, /* IPR05 */ { PINT, 0, ADC_ADI0, ADC_ADI1 } },
148 { 0xfffe0c00, 0, 16, 4, /* IPR06 */ { DMAC0, DMAC1, DMAC2, DMAC3 } },
149 { 0xfffe0c02, 0, 16, 4, /* IPR07 */ { DMAC4, DMAC5, DMAC6, DMAC7 } },
150 { 0xfffe0c04, 0, 16, 4, /* IPR08 */ { CMT0, CMT1, BSC, WDT } },
151 { 0xfffe0c06, 0, 16, 4, /* IPR09 */ { MTU0_ABCD, MTU0_VEF,
152 MTU1_AB, MTU1_VU } },
153 { 0xfffe0c08, 0, 16, 4, /* IPR10 */ { MTU2_AB, MTU2_VU,
154 MTU3_ABCD, MTU2_TCI3V } },
155 { 0xfffe0c0a, 0, 16, 4, /* IPR11 */ { MTU4_ABCD, MTU2_TCI4V,
156 MTU5, POE2_12 } },
157 { 0xfffe0c0c, 0, 16, 4, /* IPR12 */ { MTU3S_ABCD, MTU2S_TCI3V,
158 MTU4S_ABCD, MTU2S_TCI4V } },
159 { 0xfffe0c0e, 0, 16, 4, /* IPR13 */ { MTU5S, POE2_OEI3, IIC3, 0 } },
160 { 0xfffe0c10, 0, 16, 4, /* IPR14 */ { SCIF0, SCIF1, SCIF2, SCIF3 } },
161};
162
163static struct intc_mask_reg mask_registers[] __initdata = {
164 { 0xfffe0808, 0, 16, /* PINTER */
165 { 0, 0, 0, 0, 0, 0, 0, 0,
166 PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } },
167};
168
169static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups,
170 NULL, mask_registers, prio_registers, NULL);
171
15static struct plat_sci_port sci_platform_data[] = { 172static struct plat_sci_port sci_platform_data[] = {
16 { 173 {
17 .mapbase = 0xfffe8000, 174 .mapbase = 0xfffe8000,
18 .flags = UPF_BOOT_AUTOCONF, 175 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF, 176 .type = PORT_SCIF,
20 .irqs = { 241, 242, 243, 240}, 177 .irqs = { 241, 242, 243, 240 },
21 }, { 178 }, {
22 .mapbase = 0xfffe8800, 179 .mapbase = 0xfffe8800,
23 .flags = UPF_BOOT_AUTOCONF, 180 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF, 181 .type = PORT_SCIF,
25 .irqs = { 247, 244, 245, 246}, 182 .irqs = { 245, 246, 247, 244 },
26 }, { 183 }, {
27 .mapbase = 0xfffe9000, 184 .mapbase = 0xfffe9000,
28 .flags = UPF_BOOT_AUTOCONF, 185 .flags = UPF_BOOT_AUTOCONF,
29 .type = PORT_SCIF, 186 .type = PORT_SCIF,
30 .irqs = { 249, 250, 251, 248}, 187 .irqs = { 249, 250, 251, 248 },
31 }, { 188 }, {
32 .mapbase = 0xfffe9800, 189 .mapbase = 0xfffe9800,
33 .flags = UPF_BOOT_AUTOCONF, 190 .flags = UPF_BOOT_AUTOCONF,
34 .type = PORT_SCIF, 191 .type = PORT_SCIF,
35 .irqs = { 253, 254, 255, 252}, 192 .irqs = { 253, 254, 255, 252 },
36 }, { 193 }, {
37 .flags = 0, 194 .flags = 0,
38 } 195 }
@@ -57,57 +214,7 @@ static int __init sh7206_devices_setup(void)
57} 214}
58__initcall(sh7206_devices_setup); 215__initcall(sh7206_devices_setup);
59 216
60static struct ipr_data ipr_irq_table[] = {
61 { 140, 7, 12, 2 }, /* CMI0 */
62 { 164, 8, 4, 2 }, /* MTU2_TGI1A */
63 { 240, 13, 12, 3 }, /* SCIF0_BRI */
64 { 241, 13, 12, 3 }, /* SCIF0_ERI */
65 { 242, 13, 12, 3 }, /* SCIF0_RXI */
66 { 243, 13, 12, 3 }, /* SCIF0_TXI */
67 { 244, 13, 8, 3 }, /* SCIF1_BRI */
68 { 245, 13, 8, 3 }, /* SCIF1_ERI */
69 { 246, 13, 8, 3 }, /* SCIF1_RXI */
70 { 247, 13, 8, 3 }, /* SCIF1_TXI */
71 { 248, 13, 4, 3 }, /* SCIF2_BRI */
72 { 249, 13, 4, 3 }, /* SCIF2_ERI */
73 { 250, 13, 4, 3 }, /* SCIF2_RXI */
74 { 251, 13, 4, 3 }, /* SCIF2_TXI */
75 { 252, 13, 0, 3 }, /* SCIF3_BRI */
76 { 253, 13, 0, 3 }, /* SCIF3_ERI */
77 { 254, 13, 0, 3 }, /* SCIF3_RXI */
78 { 255, 13, 0, 3 }, /* SCIF3_TXI */
79};
80
81static unsigned long 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 */
96};
97
98static struct ipr_desc ipr_irq_desc = {
99 .ipr_offsets = ipr_offsets,
100 .nr_offsets = ARRAY_SIZE(ipr_offsets),
101
102 .ipr_data = ipr_irq_table,
103 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
104
105 .chip = {
106 .name = "IPR-sh7206",
107 },
108};
109
110void __init plat_irq_setup(void) 217void __init plat_irq_setup(void)
111{ 218{
112 register_ipr_controller(&ipr_irq_desc); 219 register_intc_controller(&intc_desc);
113} 220}
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index 55b750763f66..646eb6933614 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -6,12 +6,13 @@ obj-y := ex.o probe.o entry.o
6 6
7# CPU subtype setup 7# CPU subtype setup
8obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o 8obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh7709.o 9obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh7709.o 10obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o
11obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o 13obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o 14obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o
15obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o
15 16
16# Primary on-chip clocks (common) 17# Primary on-chip clocks (common)
17clock-$(CONFIG_CPU_SH3) := clock-sh3.o 18clock-$(CONFIG_CPU_SH3) := clock-sh3.o
@@ -19,5 +20,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o
19clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o 20clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o
20clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o 21clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o
21clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o 22clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o
23clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o
22 24
23obj-y += $(clock-y) 25obj-y += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index 647623b22edc..bf579e061e09 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -50,44 +50,47 @@ int __init detect_cpu_and_cache_system(void)
50 50
51 back_to_P1(); 51 back_to_P1();
52 52
53 current_cpu_data.dcache.ways = 4; 53 boot_cpu_data.dcache.ways = 4;
54 current_cpu_data.dcache.entry_shift = 4; 54 boot_cpu_data.dcache.entry_shift = 4;
55 current_cpu_data.dcache.linesz = L1_CACHE_BYTES; 55 boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
56 current_cpu_data.dcache.flags = 0; 56 boot_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 current_cpu_data.dcache.way_incr = (1 << 11); 63 boot_cpu_data.dcache.way_incr = (1 << 11);
64 current_cpu_data.dcache.entry_mask = 0x7f0; 64 boot_cpu_data.dcache.entry_mask = 0x7f0;
65 current_cpu_data.dcache.sets = 128; 65 boot_cpu_data.dcache.sets = 128;
66 current_cpu_data.type = CPU_SH7708; 66 boot_cpu_data.type = CPU_SH7708;
67 67
68 current_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC; 68 boot_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC;
69 } else { /* 7709A or 7729 */ 69 } else { /* 7709A or 7729 */
70 current_cpu_data.dcache.way_incr = (1 << 12); 70 boot_cpu_data.dcache.way_incr = (1 << 12);
71 current_cpu_data.dcache.entry_mask = 0xff0; 71 boot_cpu_data.dcache.entry_mask = 0xff0;
72 current_cpu_data.dcache.sets = 256; 72 boot_cpu_data.dcache.sets = 256;
73 current_cpu_data.type = CPU_SH7729; 73 boot_cpu_data.type = CPU_SH7729;
74 74
75#if defined(CONFIG_CPU_SUBTYPE_SH7706) 75#if defined(CONFIG_CPU_SUBTYPE_SH7706)
76 current_cpu_data.type = CPU_SH7706; 76 boot_cpu_data.type = CPU_SH7706;
77#endif 77#endif
78#if defined(CONFIG_CPU_SUBTYPE_SH7710) 78#if defined(CONFIG_CPU_SUBTYPE_SH7710)
79 current_cpu_data.type = CPU_SH7710; 79 boot_cpu_data.type = CPU_SH7710;
80#endif 80#endif
81#if defined(CONFIG_CPU_SUBTYPE_SH7712) 81#if defined(CONFIG_CPU_SUBTYPE_SH7712)
82 current_cpu_data.type = CPU_SH7712; 82 boot_cpu_data.type = CPU_SH7712;
83#endif
84#if defined(CONFIG_CPU_SUBTYPE_SH7720)
85 boot_cpu_data.type = CPU_SH7720;
83#endif 86#endif
84#if defined(CONFIG_CPU_SUBTYPE_SH7705) 87#if defined(CONFIG_CPU_SUBTYPE_SH7705)
85 current_cpu_data.type = CPU_SH7705; 88 boot_cpu_data.type = CPU_SH7705;
86 89
87#if defined(CONFIG_SH7705_CACHE_32KB) 90#if defined(CONFIG_SH7705_CACHE_32KB)
88 current_cpu_data.dcache.way_incr = (1 << 13); 91 boot_cpu_data.dcache.way_incr = (1 << 13);
89 current_cpu_data.dcache.entry_mask = 0x1ff0; 92 boot_cpu_data.dcache.entry_mask = 0x1ff0;
90 current_cpu_data.dcache.sets = 512; 93 boot_cpu_data.dcache.sets = 512;
91 ctrl_outl(CCR_CACHE_32KB, CCR3); 94 ctrl_outl(CCR_CACHE_32KB, CCR3);
92#else 95#else
93 ctrl_outl(CCR_CACHE_16KB, CCR3); 96 ctrl_outl(CCR_CACHE_16KB, CCR3);
@@ -98,9 +101,8 @@ int __init detect_cpu_and_cache_system(void)
98 /* 101 /*
99 * SH-3 doesn't have separate caches 102 * SH-3 doesn't have separate caches
100 */ 103 */
101 current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; 104 boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
102 current_cpu_data.icache = current_cpu_data.dcache; 105 boot_cpu_data.icache = boot_cpu_data.dcache;
103 106
104 return 0; 107 return 0;
105} 108}
106
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index ebd9d06d8bdd..f6c65f2659e9 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SH7705 Setup 2 * SH7705 Setup
3 * 3 *
4 * Copyright (C) 2006 Paul Mundt 4 * Copyright (C) 2006, 2007 Paul Mundt
5 * Copyright (C) 2007 Nobuhiro Iwamatsu 5 * Copyright (C) 2007 Nobuhiro Iwamatsu
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
@@ -10,8 +10,90 @@
10 */ 10 */
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h>
13#include <linux/serial.h> 14#include <linux/serial.h>
14#include <asm/sci.h> 15#include <asm/sci.h>
16#include <asm/rtc.h>
17
18enum {
19 UNUSED = 0,
20
21 /* interrupt sources */
22 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
23 PINT07, PINT815,
24 DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
25 SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
26 SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
27 ADC_ADI,
28 USB_USI0, USB_USI1,
29 TPU0, TPU1, TPU2, TPU3,
30 TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
31 RTC_ATI, RTC_PRI, RTC_CUI,
32 WDT,
33 REF_RCMI,
34
35 /* interrupt groups */
36 RTC, TMU2, DMAC, USB, SCIF2, SCIF0,
37};
38
39static struct intc_vect vectors[] __initdata = {
40 INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
41 INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
42 INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
43 INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
44 INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
45 INTC_VECT(SCIF0_TXI, 0x8e0),
46 INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
47 INTC_VECT(SCIF2_TXI, 0x960),
48 INTC_VECT(ADC_ADI, 0x980),
49 INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40),
50 INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20),
51 INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0),
52 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
53 INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
54 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
55 INTC_VECT(RTC_CUI, 0x4c0),
56 INTC_VECT(WDT, 0x560),
57 INTC_VECT(REF_RCMI, 0x580),
58};
59
60static struct intc_group groups[] __initdata = {
61 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
62 INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
63 INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
64 INTC_GROUP(USB, USB_USI0, USB_USI1),
65 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
66 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
67};
68
69static struct intc_prio priorities[] __initdata = {
70 INTC_PRIO(DMAC, 7),
71 INTC_PRIO(SCIF2, 3),
72 INTC_PRIO(SCIF0, 3),
73};
74
75static struct intc_prio_reg prio_registers[] __initdata = {
76 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
77 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } },
78 { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
79 { 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, IRQ5, IRQ4 } },
80 { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, SCIF0, SCIF2, ADC_ADI } },
81 { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, 0, USB } },
82 { 0xa4080002, 0, 16, 4, /* IPRG */ { TPU0, TPU1 } },
83 { 0xa4080004, 0, 16, 4, /* IPRH */ { TPU2, TPU3 } },
84
85};
86
87static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
88 priorities, NULL, prio_registers, NULL);
89
90static struct intc_vect vectors_irq[] __initdata = {
91 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
92 INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
93};
94
95static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL,
96 priorities, NULL, prio_registers, NULL);
15 97
16static struct plat_sci_port sci_platform_data[] = { 98static struct plat_sci_port sci_platform_data[] = {
17 { 99 {
@@ -37,8 +119,43 @@ static struct platform_device sci_device = {
37 }, 119 },
38}; 120};
39 121
122static struct resource rtc_resources[] = {
123 [0] = {
124 .start = 0xfffffec0,
125 .end = 0xfffffec0 + 0x1e,
126 .flags = IORESOURCE_IO,
127 },
128 [1] = {
129 .start = 20,
130 .flags = IORESOURCE_IRQ,
131 },
132 [2] = {
133 .start = 21,
134 .flags = IORESOURCE_IRQ,
135 },
136 [3] = {
137 .start = 22,
138 .flags = IORESOURCE_IRQ,
139 },
140};
141
142static struct sh_rtc_platform_info rtc_info = {
143 .capabilities = RTC_CAP_4_DIGIT_YEAR,
144};
145
146static struct platform_device rtc_device = {
147 .name = "sh-rtc",
148 .id = -1,
149 .num_resources = ARRAY_SIZE(rtc_resources),
150 .resource = rtc_resources,
151 .dev = {
152 .platform_data = &rtc_info,
153 },
154};
155
40static struct platform_device *sh7705_devices[] __initdata = { 156static struct platform_device *sh7705_devices[] __initdata = {
41 &sci_device, 157 &sci_device,
158 &rtc_device,
42}; 159};
43 160
44static int __init sh7705_devices_setup(void) 161static int __init sh7705_devices_setup(void)
@@ -48,51 +165,16 @@ static int __init sh7705_devices_setup(void)
48} 165}
49__initcall(sh7705_devices_setup); 166__initcall(sh7705_devices_setup);
50 167
51static struct ipr_data ipr_irq_table[] = { 168void __init plat_irq_setup_pins(int mode)
52 /* IRQ, IPR-idx, shift, priority */ 169{
53 { 16, 0, 12, 2 }, /* TMU0 TUNI*/ 170 if (mode == IRQ_MODE_IRQ) {
54 { 17, 0, 8, 2 }, /* TMU1 TUNI */ 171 register_intc_controller(&intc_desc_irq);
55 { 18, 0, 4, 2 }, /* TMU2 TUNI */ 172 return;
56 { 27, 1, 12, 2 }, /* WDT ITI */ 173 }
57 { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ 174 BUG();
58 { 21, 0, 0, 2 }, /* RTC PRI (period) */ 175}
59 { 22, 0, 0, 2 }, /* RTC CUI (carry) */
60 { 48, 4, 12, 7 }, /* DMAC DMTE0 */
61 { 49, 4, 12, 7 }, /* DMAC DMTE1 */
62 { 50, 4, 12, 7 }, /* DMAC DMTE2 */
63 { 51, 4, 12, 7 }, /* DMAC DMTE3 */
64 { 52, 4, 8, 3 }, /* SCIF0 ERI */
65 { 53, 4, 8, 3 }, /* SCIF0 RXI */
66 { 55, 4, 8, 3 }, /* SCIF0 TXI */
67 { 56, 4, 4, 3 }, /* SCIF1 ERI */
68 { 57, 4, 4, 3 }, /* SCIF1 RXI */
69 { 59, 4, 4, 3 }, /* SCIF1 TXI */
70};
71
72static unsigned long ipr_offsets[] = {
73 0xFFFFFEE2, /* 0: IPRA */
74 0xFFFFFEE4, /* 1: IPRB */
75 0xA4000016, /* 2: IPRC */
76 0xA4000018, /* 3: IPRD */
77 0xA400001A, /* 4: IPRE */
78 0xA4080000, /* 5: IPRF */
79 0xA4080002, /* 6: IPRG */
80 0xA4080004, /* 7: IPRH */
81};
82
83static struct ipr_desc ipr_irq_desc = {
84 .ipr_offsets = ipr_offsets,
85 .nr_offsets = ARRAY_SIZE(ipr_offsets),
86
87 .ipr_data = ipr_irq_table,
88 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
89
90 .chip = {
91 .name = "IPR-sh7705",
92 },
93};
94 176
95void __init plat_irq_setup(void) 177void __init plat_irq_setup(void)
96{ 178{
97 register_ipr_controller(&ipr_irq_desc); 179 register_intc_controller(&intc_desc);
98} 180}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7708.c b/arch/sh/kernel/cpu/sh3/setup-sh7708.c
deleted file mode 100644
index f933723911ca..000000000000
--- a/arch/sh/kernel/cpu/sh3/setup-sh7708.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * SH7708 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xfffffe80,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCI,
20 .irqs = { 23, 24, 25, 0 },
21 }, {
22 .flags = 0,
23 }
24};
25
26static struct platform_device sci_device = {
27 .name = "sh-sci",
28 .id = -1,
29 .dev = {
30 .platform_data = sci_platform_data,
31 },
32};
33
34static struct platform_device *sh7708_devices[] __initdata = {
35 &sci_device,
36};
37
38static int __init sh7708_devices_setup(void)
39{
40 return platform_add_devices(sh7708_devices,
41 ARRAY_SIZE(sh7708_devices));
42}
43__initcall(sh7708_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
deleted file mode 100644
index 086f8e2545af..000000000000
--- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c
+++ /dev/null
@@ -1,145 +0,0 @@
1/*
2 * SH7707/SH7709 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct resource rtc_resources[] = {
16 [0] = {
17 .start = 0xfffffec0,
18 .end = 0xfffffec0 + 0x1e,
19 .flags = IORESOURCE_IO,
20 },
21 [1] = {
22 .start = 20,
23 .flags = IORESOURCE_IRQ,
24 },
25 [2] = {
26 .start = 21,
27 .flags = IORESOURCE_IRQ,
28 },
29 [3] = {
30 .start = 22,
31 .flags = IORESOURCE_IRQ,
32 },
33};
34
35static struct plat_sci_port sci_platform_data[] = {
36 {
37 .mapbase = 0xfffffe80,
38 .flags = UPF_BOOT_AUTOCONF,
39 .type = PORT_SCI,
40 .irqs = { 23, 24, 25, 0 },
41 }, {
42 .mapbase = 0xa4000150,
43 .flags = UPF_BOOT_AUTOCONF,
44 .type = PORT_SCIF,
45 .irqs = { 56, 57, 59, 58 },
46 }, {
47 .mapbase = 0xa4000140,
48 .flags = UPF_BOOT_AUTOCONF,
49 .type = PORT_IRDA,
50 .irqs = { 52, 53, 55, 54 },
51 }, {
52 .flags = 0,
53 }
54};
55
56static struct platform_device sci_device = {
57 .name = "sh-sci",
58 .id = -1,
59 .dev = {
60 .platform_data = sci_platform_data,
61 },
62};
63
64static struct platform_device rtc_device = {
65 .name = "sh-rtc",
66 .id = -1,
67 .num_resources = ARRAY_SIZE(rtc_resources),
68 .resource = rtc_resources,
69};
70
71static struct platform_device *sh7709_devices[] __initdata = {
72 &sci_device,
73 &rtc_device,
74};
75
76static int __init sh7709_devices_setup(void)
77{
78 return platform_add_devices(sh7709_devices,
79 ARRAY_SIZE(sh7709_devices));
80}
81__initcall(sh7709_devices_setup);
82
83static struct ipr_data ipr_irq_table[] = {
84 { 16, 0, 12, 2 }, /* TMU TUNI0 */
85 { 17, 0, 8, 4 }, /* TMU TUNI1 */
86 { 18, 0, 4, 1 }, /* TMU TUNI1 */
87 { 19, 0, 4, 1 }, /* TMU TUNI1 */
88 { 20, 0, 0, 2 }, /* RTC CUI */
89 { 21, 0, 0, 2 }, /* RTC CUI */
90 { 22, 0, 0, 2 }, /* RTC CUI */
91
92 { 23, 1, 4, 3 }, /* SCI */
93 { 24, 1, 4, 3 }, /* SCI */
94 { 25, 1, 4, 3 }, /* SCI */
95 { 26, 1, 4, 3 }, /* SCI */
96 { 27, 1, 12, 3 }, /* WDT ITI */
97
98 { 32, 2, 0, 1 }, /* IRQ 0 */
99 { 33, 2, 4, 1 }, /* IRQ 1 */
100 { 34, 2, 8, 1 }, /* IRQ 2 APM */
101 { 35, 2, 12, 1 }, /* IRQ 3 TOUCHSCREEN */
102
103 { 36, 3, 0, 1 }, /* IRQ 4 */
104 { 37, 3, 4, 1 }, /* IRQ 5 */
105
106 { 48, 4, 12, 7 }, /* DMA */
107 { 49, 4, 12, 7 }, /* DMA */
108 { 50, 4, 12, 7 }, /* DMA */
109 { 51, 4, 12, 7 }, /* DMA */
110
111 { 52, 4, 8, 3 }, /* IRDA */
112 { 53, 4, 8, 3 }, /* IRDA */
113 { 54, 4, 8, 3 }, /* IRDA */
114 { 55, 4, 8, 3 }, /* IRDA */
115
116 { 56, 4, 4, 3 }, /* SCIF */
117 { 57, 4, 4, 3 }, /* SCIF */
118 { 58, 4, 4, 3 }, /* SCIF */
119 { 59, 4, 4, 3 }, /* SCIF */
120};
121
122static unsigned long ipr_offsets[] = {
123 0xfffffee2, /* 0: IPRA */
124 0xfffffee4, /* 1: IPRB */
125 0xa4000016, /* 2: IPRC */
126 0xa4000018, /* 3: IPRD */
127 0xa400001a, /* 4: IPRE */
128};
129
130static struct ipr_desc ipr_irq_desc = {
131 .ipr_offsets = ipr_offsets,
132 .nr_offsets = ARRAY_SIZE(ipr_offsets),
133
134 .ipr_data = ipr_irq_table,
135 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
136
137 .chip = {
138 .name = "IPR-sh7709",
139 },
140};
141
142void __init plat_irq_setup(void)
143{
144 register_ipr_controller(&ipr_irq_desc);
145}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
new file mode 100644
index 000000000000..60b04b1f9453
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -0,0 +1,224 @@
1/*
2 * SH3 Setup code for SH7706, SH7707, SH7708, SH7709
3 *
4 * Copyright (C) 2007 Magnus Damm
5 *
6 * Based on setup-sh7709.c
7 *
8 * Copyright (C) 2006 Paul Mundt
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/irq.h>
17#include <linux/platform_device.h>
18#include <linux/serial.h>
19#include <asm/sci.h>
20
21enum {
22 UNUSED = 0,
23
24 /* interrupt sources */
25 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
26 PINT07, PINT815,
27 DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
28 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
29 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
30 SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI,
31 ADC_ADI,
32 LCDC, PCC0, PCC1,
33 TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
34 RTC_ATI, RTC_PRI, RTC_CUI,
35 WDT,
36 REF_RCMI, REF_ROVI,
37
38 /* interrupt groups */
39 RTC, REF, TMU2, DMAC, SCI, SCIF2, SCIF0,
40};
41
42static struct intc_vect vectors[] __initdata = {
43 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
44 INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
45 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
46 INTC_VECT(RTC_CUI, 0x4c0),
47 INTC_VECT(SCI_ERI, 0x4e0), INTC_VECT(SCI_RXI, 0x500),
48 INTC_VECT(SCI_TXI, 0x520), INTC_VECT(SCI_TEI, 0x540),
49 INTC_VECT(WDT, 0x560),
50 INTC_VECT(REF_RCMI, 0x580),
51 INTC_VECT(REF_ROVI, 0x5a0),
52#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
53 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
54 defined(CONFIG_CPU_SUBTYPE_SH7709)
55 INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
56 INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
57 INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
58 INTC_VECT(ADC_ADI, 0x980),
59 INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
60 INTC_VECT(SCIF2_BRI, 0x940), INTC_VECT(SCIF2_TXI, 0x960),
61#endif
62#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
63 defined(CONFIG_CPU_SUBTYPE_SH7709)
64 INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
65 INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
66 INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
67#endif
68#if defined(CONFIG_CPU_SUBTYPE_SH7707)
69 INTC_VECT(LCDC, 0x9a0),
70 INTC_VECT(PCC0, 0x9c0), INTC_VECT(PCC1, 0x9e0),
71#endif
72};
73
74static struct intc_group groups[] __initdata = {
75 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
76 INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
77 INTC_GROUP(REF, REF_RCMI, REF_ROVI),
78 INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
79 INTC_GROUP(SCI, SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI),
80 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
81 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
82};
83
84static struct intc_prio priorities[] __initdata = {
85 INTC_PRIO(DMAC, 7),
86 INTC_PRIO(SCI, 3),
87 INTC_PRIO(SCIF2, 3),
88 INTC_PRIO(SCIF0, 3),
89};
90
91static struct intc_prio_reg prio_registers[] __initdata = {
92 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
93 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } },
94#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
95 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
96 defined(CONFIG_CPU_SUBTYPE_SH7709)
97 { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
98 { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
99 { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, 0, SCIF2, ADC_ADI } },
100#endif
101#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
102 defined(CONFIG_CPU_SUBTYPE_SH7709)
103 { 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, } },
104 { 0xa400001a, 0, 16, 4, /* IPRE */ { 0, SCIF0 } },
105#endif
106#if defined(CONFIG_CPU_SUBTYPE_SH7707)
107 { 0xa400001c, 0, 16, 4, /* IPRF */ { 0, LCDC, PCC0, PCC1, } },
108#endif
109};
110
111static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
112 priorities, NULL, prio_registers, NULL);
113
114#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
115 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
116 defined(CONFIG_CPU_SUBTYPE_SH7709)
117static struct intc_vect vectors_irq[] __initdata = {
118 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
119 INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
120};
121
122static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL,
123 priorities, NULL, prio_registers, NULL);
124#endif
125
126static struct resource rtc_resources[] = {
127 [0] = {
128 .start = 0xfffffec0,
129 .end = 0xfffffec0 + 0x1e,
130 .flags = IORESOURCE_IO,
131 },
132 [1] = {
133 .start = 20,
134 .flags = IORESOURCE_IRQ,
135 },
136 [2] = {
137 .start = 21,
138 .flags = IORESOURCE_IRQ,
139 },
140 [3] = {
141 .start = 22,
142 .flags = IORESOURCE_IRQ,
143 },
144};
145
146static struct platform_device rtc_device = {
147 .name = "sh-rtc",
148 .id = -1,
149 .num_resources = ARRAY_SIZE(rtc_resources),
150 .resource = rtc_resources,
151};
152
153static struct plat_sci_port sci_platform_data[] = {
154 {
155 .mapbase = 0xfffffe80,
156 .flags = UPF_BOOT_AUTOCONF,
157 .type = PORT_SCI,
158 .irqs = { 23, 24, 25, 0 },
159 },
160#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
161 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
162 defined(CONFIG_CPU_SUBTYPE_SH7709)
163 {
164 .mapbase = 0xa4000150,
165 .flags = UPF_BOOT_AUTOCONF,
166 .type = PORT_SCIF,
167 .irqs = { 56, 57, 59, 58 },
168 },
169#endif
170#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
171 defined(CONFIG_CPU_SUBTYPE_SH7709)
172 {
173 .mapbase = 0xa4000140,
174 .flags = UPF_BOOT_AUTOCONF,
175 .type = PORT_IRDA,
176 .irqs = { 52, 53, 55, 54 },
177 },
178#endif
179 {
180 .flags = 0,
181 }
182};
183
184static struct platform_device sci_device = {
185 .name = "sh-sci",
186 .id = -1,
187 .dev = {
188 .platform_data = sci_platform_data,
189 },
190};
191
192static struct platform_device *sh770x_devices[] __initdata = {
193 &sci_device,
194 &rtc_device,
195};
196
197static int __init sh770x_devices_setup(void)
198{
199 return platform_add_devices(sh770x_devices,
200 ARRAY_SIZE(sh770x_devices));
201}
202__initcall(sh770x_devices_setup);
203
204#define INTC_ICR1 0xa4000010UL
205#define INTC_ICR1_IRQLVL (1<<14)
206
207void __init plat_irq_setup_pins(int mode)
208{
209 if (mode == IRQ_MODE_IRQ) {
210#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
211 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
212 defined(CONFIG_CPU_SUBTYPE_SH7709)
213 ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
214 register_intc_controller(&intc_desc_irq);
215 return;
216#endif
217 }
218 BUG();
219}
220
221void __init plat_irq_setup(void)
222{
223 register_intc_controller(&intc_desc);
224}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 132284893373..84e5629fa841 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SH7710 Setup 2 * SH3 Setup code for SH7710, SH7712
3 * 3 *
4 * Copyright (C) 2006 Paul Mundt 4 * Copyright (C) 2006, 2007 Paul Mundt
5 * Copyright (C) 2007 Nobuhiro Iwamatsu 5 * Copyright (C) 2007 Nobuhiro Iwamatsu
6 * 6 *
7 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
@@ -10,8 +10,140 @@
10 */ 10 */
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h>
13#include <linux/serial.h> 14#include <linux/serial.h>
14#include <asm/sci.h> 15#include <asm/sci.h>
16#include <asm/rtc.h>
17
18enum {
19 UNUSED = 0,
20
21 /* interrupt sources */
22 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
23 DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
24 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
25 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
26 DMAC_DEI4, DMAC_DEI5,
27 IPSEC,
28 EDMAC0, EDMAC1, EDMAC2,
29 SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI,
30 SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI,
31 TMU0, TMU1, TMU2,
32 RTC_ATI, RTC_PRI, RTC_CUI,
33 WDT,
34 REF,
35
36 /* interrupt groups */
37 RTC, DMAC1, SCIF0, SCIF1, DMAC2, SIOF0, SIOF1,
38};
39
40static struct intc_vect vectors[] __initdata = {
41 INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
42 INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
43 INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
44 INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
45 INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
46 INTC_VECT(SCIF1_ERI, 0x900), INTC_VECT(SCIF1_RXI, 0x920),
47 INTC_VECT(SCIF1_BRI, 0x940), INTC_VECT(SCIF1_TXI, 0x960),
48 INTC_VECT(DMAC_DEI4, 0xb80), INTC_VECT(DMAC_DEI5, 0xba0),
49#ifdef CONFIG_CPU_SUBTYPE_SH7710
50 INTC_VECT(IPSEC, 0xbe0),
51#endif
52 INTC_VECT(EDMAC0, 0xc00), INTC_VECT(EDMAC1, 0xc20),
53 INTC_VECT(EDMAC2, 0xc40),
54 INTC_VECT(SIOF0_ERI, 0xe00), INTC_VECT(SIOF0_TXI, 0xe20),
55 INTC_VECT(SIOF0_RXI, 0xe40), INTC_VECT(SIOF0_CCI, 0xe60),
56 INTC_VECT(SIOF1_ERI, 0xe80), INTC_VECT(SIOF1_TXI, 0xea0),
57 INTC_VECT(SIOF1_RXI, 0xec0), INTC_VECT(SIOF1_CCI, 0xee0),
58 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
59 INTC_VECT(TMU2, 0x440),
60 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
61 INTC_VECT(RTC_CUI, 0x4c0),
62 INTC_VECT(WDT, 0x560),
63 INTC_VECT(REF, 0x580),
64};
65
66static struct intc_group groups[] __initdata = {
67 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
68 INTC_GROUP(DMAC1, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
69 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
70 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
71 INTC_GROUP(DMAC2, DMAC_DEI4, DMAC_DEI5),
72 INTC_GROUP(SIOF0, SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI),
73 INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI),
74};
75
76static struct intc_prio priorities[] __initdata = {
77 INTC_PRIO(DMAC1, 7),
78 INTC_PRIO(DMAC2, 7),
79 INTC_PRIO(SCIF0, 3),
80 INTC_PRIO(SCIF1, 3),
81 INTC_PRIO(SIOF0, 3),
82 INTC_PRIO(SIOF1, 3),
83 INTC_PRIO(EDMAC0, 5),
84 INTC_PRIO(EDMAC1, 5),
85 INTC_PRIO(EDMAC2, 5),
86};
87
88static struct intc_prio_reg prio_registers[] __initdata = {
89 { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
90 { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } },
91 { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
92 { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
93 { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } },
94 { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } },
95#ifdef CONFIG_CPU_SUBTYPE_SH7710
96 { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } },
97#endif
98 { 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } },
99 { 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } },
100 { 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } },
101};
102
103static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
104 priorities, NULL, prio_registers, NULL);
105
106static struct intc_vect vectors_irq[] __initdata = {
107 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
108 INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
109};
110
111static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL,
112 priorities, NULL, prio_registers, NULL);
113
114static struct resource rtc_resources[] = {
115 [0] = {
116 .start = 0xa413fec0,
117 .end = 0xa413fec0 + 0x1e,
118 .flags = IORESOURCE_IO,
119 },
120 [1] = {
121 .start = 20,
122 .flags = IORESOURCE_IRQ,
123 },
124 [2] = {
125 .start = 21,
126 .flags = IORESOURCE_IRQ,
127 },
128 [3] = {
129 .start = 22,
130 .flags = IORESOURCE_IRQ,
131 },
132};
133
134static struct sh_rtc_platform_info rtc_info = {
135 .capabilities = RTC_CAP_4_DIGIT_YEAR,
136};
137
138static struct platform_device rtc_device = {
139 .name = "sh-rtc",
140 .id = -1,
141 .num_resources = ARRAY_SIZE(rtc_resources),
142 .resource = rtc_resources,
143 .dev = {
144 .platform_data = &rtc_info,
145 },
146};
15 147
16static struct plat_sci_port sci_platform_data[] = { 148static struct plat_sci_port sci_platform_data[] = {
17 { 149 {
@@ -20,7 +152,7 @@ static struct plat_sci_port sci_platform_data[] = {
20 .type = PORT_SCIF, 152 .type = PORT_SCIF,
21 .irqs = { 52, 53, 55, 54 }, 153 .irqs = { 52, 53, 55, 54 },
22 }, { 154 }, {
23 .mapbase = 0xa4420000, 155 .mapbase = 0xa4410000,
24 .flags = UPF_BOOT_AUTOCONF, 156 .flags = UPF_BOOT_AUTOCONF,
25 .type = PORT_SCIF, 157 .type = PORT_SCIF,
26 .irqs = { 56, 57, 59, 58 }, 158 .irqs = { 56, 57, 59, 58 },
@@ -40,6 +172,7 @@ static struct platform_device sci_device = {
40 172
41static struct platform_device *sh7710_devices[] __initdata = { 173static struct platform_device *sh7710_devices[] __initdata = {
42 &sci_device, 174 &sci_device,
175 &rtc_device,
43}; 176};
44 177
45static int __init sh7710_devices_setup(void) 178static int __init sh7710_devices_setup(void)
@@ -49,59 +182,16 @@ static int __init sh7710_devices_setup(void)
49} 182}
50__initcall(sh7710_devices_setup); 183__initcall(sh7710_devices_setup);
51 184
52static struct ipr_data ipr_irq_table[] = { 185void __init plat_irq_setup_pins(int mode)
53 /* IRQ, IPR-idx, shift, priority */ 186{
54 { 16, 0, 12, 2 }, /* TMU0 TUNI*/ 187 if (mode == IRQ_MODE_IRQ) {
55 { 17, 0, 8, 2 }, /* TMU1 TUNI */ 188 register_intc_controller(&intc_desc_irq);
56 { 18, 0, 4, 2 }, /* TMU2 TUNI */ 189 return;
57 { 27, 1, 12, 2 }, /* WDT ITI */ 190 }
58 { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ 191 BUG();
59 { 21, 0, 0, 2 }, /* RTC PRI (period) */ 192}
60 { 22, 0, 0, 2 }, /* RTC CUI (carry) */
61 { 48, 4, 12, 7 }, /* DMAC DMTE0 */
62 { 49, 4, 12, 7 }, /* DMAC DMTE1 */
63 { 50, 4, 12, 7 }, /* DMAC DMTE2 */
64 { 51, 4, 12, 7 }, /* DMAC DMTE3 */
65 { 52, 4, 8, 3 }, /* SCIF0 ERI */
66 { 53, 4, 8, 3 }, /* SCIF0 RXI */
67 { 54, 4, 8, 3 }, /* SCIF0 BRI */
68 { 55, 4, 8, 3 }, /* SCIF0 TXI */
69 { 56, 4, 4, 3 }, /* SCIF1 ERI */
70 { 57, 4, 4, 3 }, /* SCIF1 RXI */
71 { 58, 4, 4, 3 }, /* SCIF1 BRI */
72 { 59, 4, 4, 3 }, /* SCIF1 TXI */
73 { 76, 5, 8, 7 }, /* DMAC DMTE4 */
74 { 77, 5, 8, 7 }, /* DMAC DMTE5 */
75 { 80, 6, 12, 5 }, /* EDMAC EINT0 */
76 { 81, 6, 8, 5 }, /* EDMAC EINT1 */
77 { 82, 6, 4, 5 }, /* EDMAC EINT2 */
78};
79
80static unsigned long ipr_offsets[] = {
81 0xA414FEE2, /* 0: IPRA */
82 0xA414FEE4, /* 1: IPRB */
83 0xA4140016, /* 2: IPRC */
84 0xA4140018, /* 3: IPRD */
85 0xA414001A, /* 4: IPRE */
86 0xA4080000, /* 5: IPRF */
87 0xA4080002, /* 6: IPRG */
88 0xA4080004, /* 7: IPRH */
89 0xA4080006, /* 8: IPRI */
90};
91
92static struct ipr_desc ipr_irq_desc = {
93 .ipr_offsets = ipr_offsets,
94 .nr_offsets = ARRAY_SIZE(ipr_offsets),
95
96 .ipr_data = ipr_irq_table,
97 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
98
99 .chip = {
100 .name = "IPR-sh7710",
101 },
102};
103 193
104void __init plat_irq_setup(void) 194void __init plat_irq_setup(void)
105{ 195{
106 register_ipr_controller(&ipr_irq_desc); 196 register_intc_controller(&intc_desc);
107} 197}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
new file mode 100644
index 000000000000..a0929b8a95ae
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -0,0 +1,210 @@
1/*
2 * SH7720 Setup
3 *
4 * Copyright (C) 2007 Markus Brunner, Mark Jonas
5 *
6 * Based on arch/sh/kernel/cpu/sh4/setup-sh7750.c:
7 *
8 * Copyright (C) 2006 Paul Mundt
9 * Copyright (C) 2006 Jamie Lenehan
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/platform_device.h>
16#include <linux/init.h>
17#include <linux/serial.h>
18#include <linux/io.h>
19#include <asm/sci.h>
20#include <asm/rtc.h>
21
22#define INTC_ICR1 0xA4140010UL
23#define INTC_ICR_IRLM 0x4000
24#define INTC_ICR_IRQ (~INTC_ICR_IRLM)
25
26static struct resource rtc_resources[] = {
27 [0] = {
28 .start = 0xa413fec0,
29 .end = 0xa413fec0 + 0x28 - 1,
30 .flags = IORESOURCE_IO,
31 },
32 [1] = {
33 /* Period IRQ */
34 .start = 21,
35 .flags = IORESOURCE_IRQ,
36 },
37 [2] = {
38 /* Carry IRQ */
39 .start = 22,
40 .flags = IORESOURCE_IRQ,
41 },
42 [3] = {
43 /* Alarm IRQ */
44 .start = 20,
45 .flags = IORESOURCE_IRQ,
46 },
47};
48
49static struct sh_rtc_platform_info rtc_info = {
50 .capabilities = RTC_CAP_4_DIGIT_YEAR,
51};
52
53static struct platform_device rtc_device = {
54 .name = "sh-rtc",
55 .id = -1,
56 .num_resources = ARRAY_SIZE(rtc_resources),
57 .resource = rtc_resources,
58 .dev = {
59 .platform_data = &rtc_info,
60 },
61};
62
63static struct plat_sci_port sci_platform_data[] = {
64 {
65 .mapbase = 0xa4430000,
66 .flags = UPF_BOOT_AUTOCONF,
67 .type = PORT_SCIF,
68 .irqs = { 80, 80, 80, 80 },
69 }, {
70 .mapbase = 0xa4438000,
71 .flags = UPF_BOOT_AUTOCONF,
72 .type = PORT_SCIF,
73 .irqs = { 81, 81, 81, 81 },
74 }, {
75
76 .flags = 0,
77 }
78};
79
80static struct platform_device sci_device = {
81 .name = "sh-sci",
82 .id = -1,
83 .dev = {
84 .platform_data = sci_platform_data,
85 },
86};
87
88static struct platform_device *sh7720_devices[] __initdata = {
89 &rtc_device,
90 &sci_device,
91};
92
93static int __init sh7720_devices_setup(void)
94{
95 return platform_add_devices(sh7720_devices,
96 ARRAY_SIZE(sh7720_devices));
97}
98__initcall(sh7720_devices_setup);
99
100enum {
101 UNUSED = 0,
102
103 /* interrupt sources */
104 TMU0, TMU1, TMU2, RTC_ATI, RTC_PRI, RTC_CUI,
105 WDT, REF_RCMI, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND,
106 IRQ0, IRQ1, IRQ2, IRQ3,
107 USBF_SPD, TMU_SUNI, IRQ5, IRQ4,
108 DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3, LCDC, SSL,
109 ADC, DMAC2_DEI4, DMAC2_DEI5, USBFI0, USBFI1, CMT,
110 SCIF0, SCIF1,
111 PINT07, PINT815, TPU0, TPU1, TPU2, TPU3, IIC,
112 SIOF0, SIOF1, MMCI0, MMCI1, MMCI2, MMCI3, PCC,
113 USBHI, AFEIF,
114 H_UDI,
115 /* interrupt groups */
116 TMU, RTC, SIM, DMAC1, USBFI, DMAC2, USB, TPU, MMC,
117};
118
119static struct intc_vect vectors[] __initdata = {
120 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
121 INTC_VECT(TMU2, 0x440), INTC_VECT(RTC_ATI, 0x480),
122 INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0),
123 INTC_VECT(SIM_ERI, 0x4e0), INTC_VECT(SIM_RXI, 0x500),
124 INTC_VECT(SIM_TXI, 0x520), INTC_VECT(SIM_TEND, 0x540),
125 INTC_VECT(WDT, 0x560), INTC_VECT(REF_RCMI, 0x580),
126 /* H_UDI cannot be masked */ INTC_VECT(TMU_SUNI, 0x6c0),
127 INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800),
128 INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840),
129 INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900),
130 INTC_VECT(SSL, 0x980), INTC_VECT(USBFI0, 0xa20),
131 INTC_VECT(USBFI1, 0xa40), INTC_VECT(USBHI, 0xa60),
132 INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0),
133 INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00),
134 INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80),
135 INTC_VECT(PINT815, 0xca0), INTC_VECT(SIOF0, 0xd00),
136 INTC_VECT(SIOF1, 0xd20), INTC_VECT(TPU0, 0xd80),
137 INTC_VECT(TPU1, 0xda0), INTC_VECT(TPU2, 0xdc0),
138 INTC_VECT(TPU3, 0xde0), INTC_VECT(IIC, 0xe00),
139 INTC_VECT(MMCI0, 0xe80), INTC_VECT(MMCI1, 0xea0),
140 INTC_VECT(MMCI2, 0xec0), INTC_VECT(MMCI3, 0xee0),
141 INTC_VECT(CMT, 0xf00), INTC_VECT(PCC, 0xf60),
142 INTC_VECT(AFEIF, 0xfe0),
143};
144
145static struct intc_group groups[] __initdata = {
146 INTC_GROUP(TMU, TMU0, TMU1, TMU2),
147 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
148 INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND),
149 INTC_GROUP(DMAC1, DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3),
150 INTC_GROUP(USBFI, USBFI0, USBFI1),
151 INTC_GROUP(DMAC2, DMAC2_DEI4, DMAC2_DEI5),
152 INTC_GROUP(TPU, TPU0, TPU1, TPU2, TPU3),
153 INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3),
154};
155
156static struct intc_prio priorities[] __initdata = {
157 INTC_PRIO(SCIF0, 2),
158 INTC_PRIO(SCIF1, 2),
159 INTC_PRIO(DMAC1, 1),
160 INTC_PRIO(DMAC2, 1),
161 INTC_PRIO(RTC, 2),
162 INTC_PRIO(TMU, 2),
163 INTC_PRIO(TPU, 2),
164};
165
166static struct intc_prio_reg prio_registers[] __initdata = {
167 { 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
168 { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
169 { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
170 { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } },
171 { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } },
172 { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } },
173 { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } },
174 { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } },
175 { 0xA4080006UL, 0, 16, 4, /* IPRI */ { SIOF0, SIOF1, MMC, PCC } },
176 { 0xA4080008UL, 0, 16, 4, /* IPRJ */ { 0, USBHI, 0, AFEIF } },
177};
178
179static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
180 priorities, NULL, prio_registers, NULL);
181
182static struct intc_sense_reg sense_registers[] __initdata = {
183 { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
184};
185
186static struct intc_vect vectors_irq[] __initdata = {
187 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
188 INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
189 INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
190};
191
192static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq,
193 NULL, priorities, NULL, prio_registers, sense_registers);
194
195void __init plat_irq_setup_pins(int mode)
196{
197 switch (mode) {
198 case IRQ_MODE_IRQ:
199 ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1);
200 register_intc_controller(&intc_irq_desc);
201 break;
202 default:
203 BUG();
204 }
205}
206
207void __init plat_irq_setup(void)
208{
209 register_intc_controller(&intc_desc);
210}
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 98d28fb1ce16..21375d777e99 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * CPU Subtype Probing for SH-4. 4 * CPU Subtype Probing for SH-4.
5 * 5 *
6 * Copyright (C) 2001 - 2006 Paul Mundt 6 * Copyright (C) 2001 - 2007 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,7 +12,6 @@
12 */ 12 */
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/smp.h>
16#include <asm/processor.h> 15#include <asm/processor.h>
17#include <asm/cache.h> 16#include <asm/cache.h>
18 17
@@ -36,37 +35,34 @@ 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 current_cpu_data.icache.way_incr = (1 << 13); 38 boot_cpu_data.icache.way_incr = (1 << 13);
40 current_cpu_data.icache.entry_shift = 5; 39 boot_cpu_data.icache.entry_shift = 5;
41 current_cpu_data.icache.sets = 256; 40 boot_cpu_data.icache.sets = 256;
42 current_cpu_data.icache.ways = 1; 41 boot_cpu_data.icache.ways = 1;
43 current_cpu_data.icache.linesz = L1_CACHE_BYTES; 42 boot_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 current_cpu_data.dcache.way_incr = (1 << 14); 47 boot_cpu_data.dcache.way_incr = (1 << 14);
49 current_cpu_data.dcache.entry_shift = 5; 48 boot_cpu_data.dcache.entry_shift = 5;
50 current_cpu_data.dcache.sets = 512; 49 boot_cpu_data.dcache.sets = 512;
51 current_cpu_data.dcache.ways = 1; 50 boot_cpu_data.dcache.ways = 1;
52 current_cpu_data.dcache.linesz = L1_CACHE_BYTES; 51 boot_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 on SH-4A parts
56 * (L2 and DSP detection only work on SH-4A)
57 */ 55 */
58 if (((pvr >> 16) & 0xff) == 0x10) { 56 if (((pvr >> 16) & 0xff) == 0x10) {
59 if ((cvr & 0x02000000) == 0)
60 current_cpu_data.flags |= CPU_HAS_L2_CACHE;
61 if ((cvr & 0x10000000) == 0) 57 if ((cvr & 0x10000000) == 0)
62 current_cpu_data.flags |= CPU_HAS_DSP; 58 boot_cpu_data.flags |= CPU_HAS_DSP;
63 59
64 current_cpu_data.flags |= CPU_HAS_LLSC; 60 boot_cpu_data.flags |= CPU_HAS_LLSC;
65 } 61 }
66 62
67 /* FPU detection works for everyone */ 63 /* FPU detection works for everyone */
68 if ((cvr & 0x20000000) == 1) 64 if ((cvr & 0x20000000) == 1)
69 current_cpu_data.flags |= CPU_HAS_FPU; 65 boot_cpu_data.flags |= CPU_HAS_FPU;
70 66
71 /* Mask off the upper chip ID */ 67 /* Mask off the upper chip ID */
72 pvr &= 0xffff; 68 pvr &= 0xffff;
@@ -77,140 +73,140 @@ int __init detect_cpu_and_cache_system(void)
77 */ 73 */
78 switch (pvr) { 74 switch (pvr) {
79 case 0x205: 75 case 0x205:
80 current_cpu_data.type = CPU_SH7750; 76 boot_cpu_data.type = CPU_SH7750;
81 current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | 77 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
82 CPU_HAS_PERF_COUNTER; 78 CPU_HAS_PERF_COUNTER;
83 break; 79 break;
84 case 0x206: 80 case 0x206:
85 current_cpu_data.type = CPU_SH7750S; 81 boot_cpu_data.type = CPU_SH7750S;
86 current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | 82 boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
87 CPU_HAS_PERF_COUNTER; 83 CPU_HAS_PERF_COUNTER;
88 break; 84 break;
89 case 0x1100: 85 case 0x1100:
90 current_cpu_data.type = CPU_SH7751; 86 boot_cpu_data.type = CPU_SH7751;
91 current_cpu_data.flags |= CPU_HAS_FPU; 87 boot_cpu_data.flags |= CPU_HAS_FPU;
92 break; 88 break;
93 case 0x2001: 89 case 0x2001:
94 case 0x2004: 90 case 0x2004:
95 current_cpu_data.type = CPU_SH7770; 91 boot_cpu_data.type = CPU_SH7770;
96 current_cpu_data.icache.ways = 4; 92 boot_cpu_data.icache.ways = 4;
97 current_cpu_data.dcache.ways = 4; 93 boot_cpu_data.dcache.ways = 4;
98 94
99 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC; 95 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
100 break; 96 break;
101 case 0x2006: 97 case 0x2006:
102 case 0x200A: 98 case 0x200A:
103 if (prr == 0x61) 99 if (prr == 0x61)
104 current_cpu_data.type = CPU_SH7781; 100 boot_cpu_data.type = CPU_SH7781;
105 else 101 else
106 current_cpu_data.type = CPU_SH7780; 102 boot_cpu_data.type = CPU_SH7780;
107 103
108 current_cpu_data.icache.ways = 4; 104 boot_cpu_data.icache.ways = 4;
109 current_cpu_data.dcache.ways = 4; 105 boot_cpu_data.dcache.ways = 4;
110 106
111 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | 107 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
112 CPU_HAS_LLSC; 108 CPU_HAS_LLSC;
113 break; 109 break;
114 case 0x3000: 110 case 0x3000:
115 case 0x3003: 111 case 0x3003:
116 case 0x3009: 112 case 0x3009:
117 current_cpu_data.type = CPU_SH7343; 113 boot_cpu_data.type = CPU_SH7343;
118 current_cpu_data.icache.ways = 4; 114 boot_cpu_data.icache.ways = 4;
119 current_cpu_data.dcache.ways = 4; 115 boot_cpu_data.dcache.ways = 4;
120 current_cpu_data.flags |= CPU_HAS_LLSC; 116 boot_cpu_data.flags |= CPU_HAS_LLSC;
121 break; 117 break;
122 case 0x3004: 118 case 0x3004:
123 case 0x3007: 119 case 0x3007:
124 current_cpu_data.type = CPU_SH7785; 120 boot_cpu_data.type = CPU_SH7785;
125 current_cpu_data.icache.ways = 4; 121 boot_cpu_data.icache.ways = 4;
126 current_cpu_data.dcache.ways = 4; 122 boot_cpu_data.dcache.ways = 4;
127 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | 123 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
128 CPU_HAS_LLSC; 124 CPU_HAS_LLSC;
129 break; 125 break;
130 case 0x3008: 126 case 0x3008:
131 if (prr == 0xa0) { 127 if (prr == 0xa0) {
132 current_cpu_data.type = CPU_SH7722; 128 boot_cpu_data.type = CPU_SH7722;
133 current_cpu_data.icache.ways = 4; 129 boot_cpu_data.icache.ways = 4;
134 current_cpu_data.dcache.ways = 4; 130 boot_cpu_data.dcache.ways = 4;
135 current_cpu_data.flags |= CPU_HAS_LLSC; 131 boot_cpu_data.flags |= CPU_HAS_LLSC;
136 } 132 }
137 break; 133 break;
138 case 0x4000: /* 1st cut */ 134 case 0x4000: /* 1st cut */
139 case 0x4001: /* 2nd cut */ 135 case 0x4001: /* 2nd cut */
140 current_cpu_data.type = CPU_SHX3; 136 boot_cpu_data.type = CPU_SHX3;
141 current_cpu_data.icache.ways = 4; 137 boot_cpu_data.icache.ways = 4;
142 current_cpu_data.dcache.ways = 4; 138 boot_cpu_data.dcache.ways = 4;
143 current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | 139 boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
144 CPU_HAS_LLSC; 140 CPU_HAS_LLSC;
145 break; 141 break;
146 case 0x8000: 142 case 0x8000:
147 current_cpu_data.type = CPU_ST40RA; 143 boot_cpu_data.type = CPU_ST40RA;
148 current_cpu_data.flags |= CPU_HAS_FPU; 144 boot_cpu_data.flags |= CPU_HAS_FPU;
149 break; 145 break;
150 case 0x8100: 146 case 0x8100:
151 current_cpu_data.type = CPU_ST40GX1; 147 boot_cpu_data.type = CPU_ST40GX1;
152 current_cpu_data.flags |= CPU_HAS_FPU; 148 boot_cpu_data.flags |= CPU_HAS_FPU;
153 break; 149 break;
154 case 0x700: 150 case 0x700:
155 current_cpu_data.type = CPU_SH4_501; 151 boot_cpu_data.type = CPU_SH4_501;
156 current_cpu_data.icache.ways = 2; 152 boot_cpu_data.icache.ways = 2;
157 current_cpu_data.dcache.ways = 2; 153 boot_cpu_data.dcache.ways = 2;
158 break; 154 break;
159 case 0x600: 155 case 0x600:
160 current_cpu_data.type = CPU_SH4_202; 156 boot_cpu_data.type = CPU_SH4_202;
161 current_cpu_data.icache.ways = 2; 157 boot_cpu_data.icache.ways = 2;
162 current_cpu_data.dcache.ways = 2; 158 boot_cpu_data.dcache.ways = 2;
163 current_cpu_data.flags |= CPU_HAS_FPU; 159 boot_cpu_data.flags |= CPU_HAS_FPU;
164 break; 160 break;
165 case 0x500 ... 0x501: 161 case 0x500 ... 0x501:
166 switch (prr) { 162 switch (prr) {
167 case 0x10: 163 case 0x10:
168 current_cpu_data.type = CPU_SH7750R; 164 boot_cpu_data.type = CPU_SH7750R;
169 break; 165 break;
170 case 0x11: 166 case 0x11:
171 current_cpu_data.type = CPU_SH7751R; 167 boot_cpu_data.type = CPU_SH7751R;
172 break; 168 break;
173 case 0x50 ... 0x5f: 169 case 0x50 ... 0x5f:
174 current_cpu_data.type = CPU_SH7760; 170 boot_cpu_data.type = CPU_SH7760;
175 break; 171 break;
176 } 172 }
177 173
178 current_cpu_data.icache.ways = 2; 174 boot_cpu_data.icache.ways = 2;
179 current_cpu_data.dcache.ways = 2; 175 boot_cpu_data.dcache.ways = 2;
180 176
181 current_cpu_data.flags |= CPU_HAS_FPU; 177 boot_cpu_data.flags |= CPU_HAS_FPU;
182 178
183 break; 179 break;
184 default: 180 default:
185 current_cpu_data.type = CPU_SH_NONE; 181 boot_cpu_data.type = CPU_SH_NONE;
186 break; 182 break;
187 } 183 }
188 184
189#ifdef CONFIG_SH_DIRECT_MAPPED 185#ifdef CONFIG_SH_DIRECT_MAPPED
190 current_cpu_data.icache.ways = 1; 186 boot_cpu_data.icache.ways = 1;
191 current_cpu_data.dcache.ways = 1; 187 boot_cpu_data.dcache.ways = 1;
192#endif 188#endif
193 189
194#ifdef CONFIG_CPU_HAS_PTEA 190#ifdef CONFIG_CPU_HAS_PTEA
195 current_cpu_data.flags |= CPU_HAS_PTEA; 191 boot_cpu_data.flags |= CPU_HAS_PTEA;
196#endif 192#endif
197 193
198 /* 194 /*
199 * On anything that's not a direct-mapped cache, look to the CVR 195 * On anything that's not a direct-mapped cache, look to the CVR
200 * for I/D-cache specifics. 196 * for I/D-cache specifics.
201 */ 197 */
202 if (current_cpu_data.icache.ways > 1) { 198 if (boot_cpu_data.icache.ways > 1) {
203 size = sizes[(cvr >> 20) & 0xf]; 199 size = sizes[(cvr >> 20) & 0xf];
204 current_cpu_data.icache.way_incr = (size >> 1); 200 boot_cpu_data.icache.way_incr = (size >> 1);
205 current_cpu_data.icache.sets = (size >> 6); 201 boot_cpu_data.icache.sets = (size >> 6);
206 202
207 } 203 }
208 204
209 /* And the rest of the D-cache */ 205 /* And the rest of the D-cache */
210 if (current_cpu_data.dcache.ways > 1) { 206 if (boot_cpu_data.dcache.ways > 1) {
211 size = sizes[(cvr >> 16) & 0xf]; 207 size = sizes[(cvr >> 16) & 0xf];
212 current_cpu_data.dcache.way_incr = (size >> 1); 208 boot_cpu_data.dcache.way_incr = (size >> 1);
213 current_cpu_data.dcache.sets = (size >> 6); 209 boot_cpu_data.dcache.sets = (size >> 6);
214 } 210 }
215 211
216 /* 212 /*
@@ -218,7 +214,7 @@ int __init detect_cpu_and_cache_system(void)
218 * 214 *
219 * SH-4A's have an optional PIPT L2. 215 * SH-4A's have an optional PIPT L2.
220 */ 216 */
221 if (current_cpu_data.flags & CPU_HAS_L2_CACHE) { 217 if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
222 /* 218 /*
223 * Size calculation is much more sensible 219 * Size calculation is much more sensible
224 * than it is for the L1. 220 * than it is for the L1.
@@ -229,22 +225,22 @@ int __init detect_cpu_and_cache_system(void)
229 225
230 BUG_ON(!size); 226 BUG_ON(!size);
231 227
232 current_cpu_data.scache.way_incr = (1 << 16); 228 boot_cpu_data.scache.way_incr = (1 << 16);
233 current_cpu_data.scache.entry_shift = 5; 229 boot_cpu_data.scache.entry_shift = 5;
234 current_cpu_data.scache.ways = 4; 230 boot_cpu_data.scache.ways = 4;
235 current_cpu_data.scache.linesz = L1_CACHE_BYTES; 231 boot_cpu_data.scache.linesz = L1_CACHE_BYTES;
236 232
237 current_cpu_data.scache.entry_mask = 233 boot_cpu_data.scache.entry_mask =
238 (current_cpu_data.scache.way_incr - 234 (boot_cpu_data.scache.way_incr -
239 current_cpu_data.scache.linesz); 235 boot_cpu_data.scache.linesz);
240 236
241 current_cpu_data.scache.sets = size / 237 boot_cpu_data.scache.sets = size /
242 (current_cpu_data.scache.linesz * 238 (boot_cpu_data.scache.linesz *
243 current_cpu_data.scache.ways); 239 boot_cpu_data.scache.ways);
244 240
245 current_cpu_data.scache.way_size = 241 boot_cpu_data.scache.way_size =
246 (current_cpu_data.scache.sets * 242 (boot_cpu_data.scache.sets *
247 current_cpu_data.scache.linesz); 243 boot_cpu_data.scache.linesz);
248 } 244 }
249 245
250 return 0; 246 return 0;
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index f2286de22bd5..523f68a9ce0e 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -104,7 +104,7 @@ enum {
104 DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, 104 DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
105}; 105};
106 106
107static struct intc_vect vectors[] = { 107static struct intc_vect vectors[] __initdata = {
108 INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620), 108 INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
109 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), 109 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
110 INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), 110 INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
@@ -118,7 +118,7 @@ static struct intc_vect vectors[] = {
118 INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0), 118 INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
119}; 119};
120 120
121static struct intc_group groups[] = { 121static struct intc_group groups[] __initdata = {
122 INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), 122 INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
123 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), 123 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
124 INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI), 124 INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
@@ -126,20 +126,20 @@ static struct intc_group groups[] = {
126 INTC_GROUP(REF, REF_RCMI, REF_ROVI), 126 INTC_GROUP(REF, REF_RCMI, REF_ROVI),
127}; 127};
128 128
129static struct intc_prio priorities[] = { 129static struct intc_prio priorities[] __initdata = {
130 INTC_PRIO(SCIF, 3), 130 INTC_PRIO(SCIF, 3),
131 INTC_PRIO(SCI1, 3), 131 INTC_PRIO(SCI1, 3),
132 INTC_PRIO(DMAC, 7), 132 INTC_PRIO(DMAC, 7),
133}; 133};
134 134
135static struct intc_prio_reg prio_registers[] = { 135static struct intc_prio_reg prio_registers[] __initdata = {
136 { 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, 136 { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
137 { 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, 137 { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
138 { 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, 138 { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
139 { 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, 139 { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
140 { 0xfe080000, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0, 140 { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
141 TMU4, TMU3, 141 TMU4, TMU3,
142 PCIC1, PCIC0_PCISERR } }, 142 PCIC1, PCIC0_PCISERR } },
143}; 143};
144 144
145static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, 145static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
@@ -150,13 +150,13 @@ static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
150 defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ 150 defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
151 defined(CONFIG_CPU_SUBTYPE_SH7751) || \ 151 defined(CONFIG_CPU_SUBTYPE_SH7751) || \
152 defined(CONFIG_CPU_SUBTYPE_SH7091) 152 defined(CONFIG_CPU_SUBTYPE_SH7091)
153static struct intc_vect vectors_dma4[] = { 153static struct intc_vect vectors_dma4[] __initdata = {
154 INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), 154 INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
155 INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), 155 INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
156 INTC_VECT(DMAC_DMAE, 0x6c0), 156 INTC_VECT(DMAC_DMAE, 0x6c0),
157}; 157};
158 158
159static struct intc_group groups_dma4[] = { 159static struct intc_group groups_dma4[] __initdata = {
160 INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, 160 INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
161 DMAC_DMTE3, DMAC_DMAE), 161 DMAC_DMTE3, DMAC_DMAE),
162}; 162};
@@ -168,7 +168,7 @@ static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4",
168 168
169/* SH7750R and SH7751R both have 8-channel DMA controllers */ 169/* SH7750R and SH7751R both have 8-channel DMA controllers */
170#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R) 170#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
171static struct intc_vect vectors_dma8[] = { 171static struct intc_vect vectors_dma8[] __initdata = {
172 INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), 172 INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
173 INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), 173 INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
174 INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0), 174 INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
@@ -176,7 +176,7 @@ static struct intc_vect vectors_dma8[] = {
176 INTC_VECT(DMAC_DMAE, 0x6c0), 176 INTC_VECT(DMAC_DMAE, 0x6c0),
177}; 177};
178 178
179static struct intc_group groups_dma8[] = { 179static struct intc_group groups_dma8[] __initdata = {
180 INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, 180 INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
181 DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, 181 DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
182 DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE), 182 DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
@@ -191,11 +191,11 @@ static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8",
191#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ 191#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
192 defined(CONFIG_CPU_SUBTYPE_SH7751) || \ 192 defined(CONFIG_CPU_SUBTYPE_SH7751) || \
193 defined(CONFIG_CPU_SUBTYPE_SH7751R) 193 defined(CONFIG_CPU_SUBTYPE_SH7751R)
194static struct intc_vect vectors_tmu34[] = { 194static struct intc_vect vectors_tmu34[] __initdata = {
195 INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80), 195 INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
196}; 196};
197 197
198static struct intc_mask_reg mask_registers[] = { 198static struct intc_mask_reg mask_registers[] __initdata = {
199 { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ 199 { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
200 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201 0, 0, 0, 0, 0, 0, TMU4, TMU3, 201 0, 0, 0, 0, 0, 0, TMU4, TMU3,
@@ -210,7 +210,7 @@ static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34",
210#endif 210#endif
211 211
212/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */ 212/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
213static struct intc_vect vectors_irlm[] = { 213static struct intc_vect vectors_irlm[] __initdata = {
214 INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), 214 INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
215 INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), 215 INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
216}; 216};
@@ -220,14 +220,14 @@ static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL,
220 220
221/* SH7751 and SH7751R both have PCI */ 221/* SH7751 and SH7751R both have PCI */
222#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R) 222#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
223static struct intc_vect vectors_pci[] = { 223static struct intc_vect vectors_pci[] __initdata = {
224 INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0), 224 INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
225 INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0), 225 INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
226 INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60), 226 INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
227 INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20), 227 INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
228}; 228};
229 229
230static struct intc_group groups_pci[] = { 230static struct intc_group groups_pci[] __initdata = {
231 INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, 231 INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
232 PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), 232 PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
233}; 233};
@@ -282,13 +282,19 @@ void __init plat_irq_setup(void)
282#define INTC_ICR 0xffd00000UL 282#define INTC_ICR 0xffd00000UL
283#define INTC_ICR_IRLM (1<<7) 283#define INTC_ICR_IRLM (1<<7)
284 284
285/* enable individual interrupt mode for external interupts */ 285void __init plat_irq_setup_pins(int mode)
286void __init ipr_irq_enable_irlm(void)
287{ 286{
288#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091) 287#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091)
289 BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */ 288 BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */
289 return;
290#endif 290#endif
291 register_intc_controller(&intc_desc_irlm);
292 291
293 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 292 switch (mode) {
293 case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
294 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
295 register_intc_controller(&intc_desc_irlm);
296 break;
297 default:
298 BUG();
299 }
294} 300}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 47fa27056253..7a898cb1d940 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -12,6 +12,136 @@
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <asm/sci.h> 13#include <asm/sci.h>
14 14
15enum {
16 UNUSED = 0,
17
18 /* interrupt sources */
19 IRL0, IRL1, IRL2, IRL3,
20 HUDI, GPIOI,
21 DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
22 DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
23 DMAC_DMAE,
24 IRQ4, IRQ5, IRQ6, IRQ7,
25 HCAN20, HCAN21,
26 SSI0, SSI1,
27 HAC0, HAC1,
28 I2C0, I2C1,
29 USB, LCDC,
30 DMABRG0, DMABRG1, DMABRG2,
31 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
32 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
33 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
34 SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI,
35 HSPI,
36 MMCIF0, MMCIF1, MMCIF2, MMCIF3,
37 MFI, ADC, CMT,
38 TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
39 WDT,
40 REF_RCMI, REF_ROVI,
41
42 /* interrupt groups */
43 DMAC, DMABRG, SCIF0, SCIF1, SCIF2, SIM, MMCIF, TMU2, REF,
44};
45
46static struct intc_vect vectors[] __initdata = {
47 INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
48 INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
49 INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
50 INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
51 INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
52 INTC_VECT(DMAC_DMAE, 0x6c0),
53 INTC_VECT(IRQ4, 0x800), INTC_VECT(IRQ5, 0x820),
54 INTC_VECT(IRQ6, 0x840), INTC_VECT(IRQ6, 0x860),
55 INTC_VECT(HCAN20, 0x900), INTC_VECT(HCAN21, 0x920),
56 INTC_VECT(SSI0, 0x940), INTC_VECT(SSI1, 0x960),
57 INTC_VECT(HAC0, 0x980), INTC_VECT(HAC1, 0x9a0),
58 INTC_VECT(I2C0, 0x9c0), INTC_VECT(I2C1, 0x9e0),
59 INTC_VECT(USB, 0xa00), INTC_VECT(LCDC, 0xa20),
60 INTC_VECT(DMABRG0, 0xa80), INTC_VECT(DMABRG1, 0xaa0),
61 INTC_VECT(DMABRG2, 0xac0),
62 INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
63 INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
64 INTC_VECT(SCIF1_ERI, 0xb00), INTC_VECT(SCIF1_RXI, 0xb20),
65 INTC_VECT(SCIF1_BRI, 0xb40), INTC_VECT(SCIF1_TXI, 0xb60),
66 INTC_VECT(SCIF2_ERI, 0xb80), INTC_VECT(SCIF2_RXI, 0xba0),
67 INTC_VECT(SCIF2_BRI, 0xbc0), INTC_VECT(SCIF2_TXI, 0xbe0),
68 INTC_VECT(SIM_ERI, 0xc00), INTC_VECT(SIM_RXI, 0xc20),
69 INTC_VECT(SIM_TXI, 0xc40), INTC_VECT(SIM_TEI, 0xc60),
70 INTC_VECT(HSPI, 0xc80),
71 INTC_VECT(MMCIF0, 0xd00), INTC_VECT(MMCIF1, 0xd20),
72 INTC_VECT(MMCIF2, 0xd40), INTC_VECT(MMCIF3, 0xd60),
73 INTC_VECT(MFI, 0xe80), /* 0xf80 according to data sheet */
74 INTC_VECT(ADC, 0xf80), INTC_VECT(CMT, 0xfa0),
75 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
76 INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
77 INTC_VECT(WDT, 0x560),
78 INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
79};
80
81static struct intc_group groups[] __initdata = {
82 INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
83 DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
84 DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
85 INTC_GROUP(DMABRG, DMABRG0, DMABRG1, DMABRG2),
86 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
87 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
88 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
89 INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI),
90 INTC_GROUP(MMCIF, MMCIF0, MMCIF1, MMCIF2, MMCIF3),
91 INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
92 INTC_GROUP(REF, REF_RCMI, REF_ROVI),
93};
94
95static struct intc_prio priorities[] __initdata = {
96 INTC_PRIO(SCIF0, 3),
97 INTC_PRIO(SCIF1, 3),
98 INTC_PRIO(SCIF2, 3),
99 INTC_PRIO(SIM, 3),
100 INTC_PRIO(DMAC, 7),
101 INTC_PRIO(DMABRG, 13),
102};
103
104static struct intc_mask_reg mask_registers[] __initdata = {
105 { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
106 { IRQ4, IRQ5, IRQ6, IRQ7, 0, 0, HCAN20, HCAN21,
107 SSI0, SSI1, HAC0, HAC1, I2C0, I2C1, USB, LCDC,
108 0, DMABRG0, DMABRG1, DMABRG2,
109 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
110 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
111 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, } },
112 { 0xfe080044, 0xfe080064, 32, /* INTMSK04 / INTMSKCLR04 */
113 { 0, 0, 0, 0, 0, 0, 0, 0,
114 SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI,
115 HSPI, MMCIF0, MMCIF1, MMCIF2,
116 MMCIF3, 0, 0, 0, 0, 0, 0, 0,
117 0, MFI, 0, 0, 0, 0, ADC, CMT, } },
118};
119
120static struct intc_prio_reg prio_registers[] __initdata = {
121 { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } },
122 { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } },
123 { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, 0, HUDI } },
124 { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
125 { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
126 { 0xfe080004, 0, 32, 4, /* INTPRI04 */ { HCAN20, HCAN21, SSI0, SSI1,
127 HAC0, HAC1, I2C0, I2C1 } },
128 { 0xfe080008, 0, 32, 4, /* INTPRI08 */ { USB, LCDC, DMABRG, SCIF0,
129 SCIF1, SCIF2, SIM, HSPI } },
130 { 0xfe08000c, 0, 32, 4, /* INTPRI0C */ { 0, 0, MMCIF, 0,
131 MFI, 0, ADC, CMT } },
132};
133
134static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups,
135 priorities, mask_registers, prio_registers, NULL);
136
137static struct intc_vect vectors_irq[] __initdata = {
138 INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
139 INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
140};
141
142static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups,
143 priorities, mask_registers, prio_registers, NULL);
144
15static struct plat_sci_port sci_platform_data[] = { 145static struct plat_sci_port sci_platform_data[] = {
16 { 146 {
17 .mapbase = 0xfe600000, 147 .mapbase = 0xfe600000,
@@ -29,6 +159,11 @@ static struct plat_sci_port sci_platform_data[] = {
29 .type = PORT_SCIF, 159 .type = PORT_SCIF,
30 .irqs = { 76, 77, 79, 78 }, 160 .irqs = { 76, 77, 79, 78 },
31 }, { 161 }, {
162 .mapbase = 0xfe480000,
163 .flags = UPF_BOOT_AUTOCONF,
164 .type = PORT_SCI,
165 .irqs = { 80, 81, 82, 0 },
166 }, {
32 .flags = 0, 167 .flags = 0,
33 } 168 }
34}; 169};
@@ -52,114 +187,18 @@ static int __init sh7760_devices_setup(void)
52} 187}
53__initcall(sh7760_devices_setup); 188__initcall(sh7760_devices_setup);
54 189
55static struct intc2_data intc2_irq_table[] = { 190void __init plat_irq_setup_pins(int mode)
56 {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ 191{
57 {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ 192 switch (mode) {
58 {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ 193 case IRQ_MODE_IRQ:
59 {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ 194 register_intc_controller(&intc_desc_irq);
60 {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ 195 break;
61 {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ 196 default:
62 {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ 197 BUG();
63 {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ 198 }
64 {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ 199}
65 {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */
66 {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */
67 {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */
68 {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */
69 {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */
70 {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */
71 {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */
72 {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */
73 {65, 8, 24, 0, 16, 3}, /* LCDC */
74 {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */
75 {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */
76 {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */
77 {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */
78 {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */
79 {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */
80 {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */
81 {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */
82 {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */
83 {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */
84 {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */
85 {80, 8, 4, 4, 23, 3}, /* SIM_ERI */
86 {81, 8, 4, 4, 22, 3}, /* SIM_RXI */
87 {82, 8, 4, 4, 21, 3}, /* SIM_TXI */
88 {83, 8, 4, 4, 20, 3}, /* SIM_TEI */
89 {84, 8, 0, 4, 19, 3}, /* HSPII */
90 {88, 12, 20, 4, 18, 3}, /* MMCI0 */
91 {89, 12, 20, 4, 17, 3}, /* MMCI1 */
92 {90, 12, 20, 4, 16, 3}, /* MMCI2 */
93 {91, 12, 20, 4, 15, 3}, /* MMCI3 */
94 {92, 12, 12, 4, 6, 3}, /* MFI */
95 {108,12, 4, 4, 1, 3}, /* ADC */
96 {109,12, 0, 4, 0, 3}, /* CMTI */
97};
98
99static struct intc2_desc intc2_irq_desc __read_mostly = {
100 .prio_base = 0xfe080000,
101 .msk_base = 0xfe080040,
102 .mskclr_base = 0xfe080060,
103
104 .intc2_data = intc2_irq_table,
105 .nr_irqs = ARRAY_SIZE(intc2_irq_table),
106
107 .chip = {
108 .name = "INTC2-sh7760",
109 },
110};
111
112static struct ipr_data ipr_irq_table[] = {
113 /* IRQ, IPR-idx, shift, priority */
114 { 16, 0, 12, 2 }, /* TMU0 TUNI*/
115 { 17, 0, 8, 2 }, /* TMU1 TUNI */
116 { 18, 0, 4, 2 }, /* TMU2 TUNI */
117 { 19, 0, 4, 2 }, /* TMU2 TIPCI */
118 { 27, 1, 12, 2 }, /* WDT ITI */
119 { 28, 1, 8, 2 }, /* REF RCMI */
120 { 29, 1, 8, 2 }, /* REF ROVI */
121 { 32, 2, 0, 7 }, /* HUDI */
122 { 33, 2, 12, 7 }, /* GPIOI */
123 { 34, 2, 8, 7 }, /* DMAC DMTE0 */
124 { 35, 2, 8, 7 }, /* DMAC DMTE1 */
125 { 36, 2, 8, 7 }, /* DMAC DMTE2 */
126 { 37, 2, 8, 7 }, /* DMAC DMTE3 */
127 { 38, 2, 8, 7 }, /* DMAC DMAE */
128 { 44, 2, 8, 7 }, /* DMAC DMTE4 */
129 { 45, 2, 8, 7 }, /* DMAC DMTE5 */
130 { 46, 2, 8, 7 }, /* DMAC DMTE6 */
131 { 47, 2, 8, 7 }, /* DMAC DMTE7 */
132/* these here are only valid if INTC_ICR bit 7 is set to 1!
133 * XXX: maybe CONFIG_SH_IRLMODE symbol? SH7751 could use it too */
134#if 0
135 { 2, 3, 12, 3 }, /* IRL0 */
136 { 5, 3, 8, 3 }, /* IRL1 */
137 { 8, 3, 4, 3 }, /* IRL2 */
138 { 11, 3, 0, 3 }, /* IRL3 */
139#endif
140};
141
142static unsigned long ipr_offsets[] = {
143 0xffd00004UL, /* 0: IPRA */
144 0xffd00008UL, /* 1: IPRB */
145 0xffd0000cUL, /* 2: IPRC */
146 0xffd00010UL, /* 3: IPRD */
147};
148
149static struct ipr_desc ipr_irq_desc = {
150 .ipr_offsets = ipr_offsets,
151 .nr_offsets = ARRAY_SIZE(ipr_offsets),
152
153 .ipr_data = ipr_irq_table,
154 .nr_irqs = ARRAY_SIZE(ipr_irq_table),
155
156 .chip = {
157 .name = "IPR-sh7760",
158 },
159};
160 200
161void __init plat_irq_setup(void) 201void __init plat_irq_setup(void)
162{ 202{
163 register_intc2_controller(&intc2_irq_desc); 203 register_intc_controller(&intc_desc);
164 register_ipr_controller(&ipr_irq_desc);
165} 204}
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index c21512c6044e..b22a78c807e6 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -58,11 +58,11 @@ do { \
58 */ 58 */
59void sq_flush_range(unsigned long start, unsigned int len) 59void sq_flush_range(unsigned long start, unsigned int len)
60{ 60{
61 volatile unsigned long *sq = (unsigned long *)start; 61 unsigned long *sq = (unsigned long *)start;
62 62
63 /* Flush the queues */ 63 /* Flush the queues */
64 for (len >>= 5; len--; sq += 8) 64 for (len >>= 5; len--; sq += 8)
65 prefetchw((void *)sq); 65 prefetchw(sq);
66 66
67 /* Wait for completion */ 67 /* Wait for completion */
68 store_queue_barrier(); 68 store_queue_barrier();
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index e6a1fb5f8484..24539873943a 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -10,6 +10,9 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o 10obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
11obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o 11obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
12 12
13# SMP setup
14smp-$(CONFIG_CPU_SUBTYPE_SHX3) := smp-shx3.o
15
13# Primary on-chip clocks (common) 16# Primary on-chip clocks (common)
14clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o 17clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
15clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o 18clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
@@ -18,4 +21,5 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
18clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o 21clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
19clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o 22clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
20 23
21obj-y += $(clock-y) 24obj-y += $(clock-y)
25obj-$(CONFIG_SMP) += $(smp-y)
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 91d61cf91ba1..c0a3f079dfdc 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -41,3 +41,7 @@ static int __init sh7343_devices_setup(void)
41 ARRAY_SIZE(sh7343_devices)); 41 ARRAY_SIZE(sh7343_devices));
42} 42}
43__initcall(sh7343_devices_setup); 43__initcall(sh7343_devices_setup);
44
45void __init plat_irq_setup(void)
46{
47}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 25b913e07e2c..55f66104431d 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -84,7 +84,7 @@ enum {
84 SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI, 84 SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI,
85}; 85};
86 86
87static struct intc_vect vectors[] = { 87static struct intc_vect vectors[] __initdata = {
88 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), 88 INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
89 INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), 89 INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
90 INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), 90 INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
@@ -117,7 +117,7 @@ static struct intc_vect vectors[] = {
117 INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580), 117 INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580),
118}; 118};
119 119
120static struct intc_group groups[] = { 120static struct intc_group groups[] __initdata = {
121 INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI), 121 INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI),
122 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), 122 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
123 INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3), 123 INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3),
@@ -130,7 +130,7 @@ static struct intc_group groups[] = {
130 INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), 130 INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3),
131}; 131};
132 132
133static struct intc_prio priorities[] = { 133static struct intc_prio priorities[] __initdata = {
134 INTC_PRIO(SCIF0, 3), 134 INTC_PRIO(SCIF0, 3),
135 INTC_PRIO(SCIF1, 3), 135 INTC_PRIO(SCIF1, 3),
136 INTC_PRIO(SCIF2, 3), 136 INTC_PRIO(SCIF2, 3),
@@ -138,7 +138,7 @@ static struct intc_prio priorities[] = {
138 INTC_PRIO(TMU1, 2), 138 INTC_PRIO(TMU1, 2),
139}; 139};
140 140
141static struct intc_mask_reg mask_registers[] = { 141static struct intc_mask_reg mask_registers[] __initdata = {
142 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ 142 { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
143 { } }, 143 { } },
144 { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ 144 { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
@@ -168,24 +168,24 @@ static struct intc_mask_reg mask_registers[] = {
168 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 168 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
169}; 169};
170 170
171static struct intc_prio_reg prio_registers[] = { 171static struct intc_prio_reg prio_registers[] __initdata = {
172 { 0xa4080000, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, 172 { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } },
173 { 0xa4080004, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, 173 { 0xa4080004, 0, 16, 4, /* IPRB */ { JPU, LCDC, SIM } },
174 { 0xa4080008, 16, 4, /* IPRC */ { } }, 174 { 0xa4080008, 0, 16, 4, /* IPRC */ { } },
175 { 0xa408000c, 16, 4, /* IPRD */ { } }, 175 { 0xa408000c, 0, 16, 4, /* IPRD */ { } },
176 { 0xa4080010, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, 176 { 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } },
177 { 0xa4080014, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, 177 { 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } },
178 { 0xa4080018, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, 178 { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } },
179 { 0xa408001c, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, 179 { 0xa408001c, 0, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } },
180 { 0xa4080020, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, 180 { 0xa4080020, 0, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } },
181 { 0xa4080024, 16, 4, /* IPRJ */ { 0, 0, SIU } }, 181 { 0xa4080024, 0, 16, 4, /* IPRJ */ { 0, 0, SIU } },
182 { 0xa4080028, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, 182 { 0xa4080028, 0, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } },
183 { 0xa408002c, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, 183 { 0xa408002c, 0, 16, 4, /* IPRL */ { TWODG, 0, TPU } },
184 { 0xa4140010, 32, 4, /* INTPRI00 */ 184 { 0xa4140010, 0, 32, 4, /* INTPRI00 */
185 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 185 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
186}; 186};
187 187
188static struct intc_sense_reg sense_registers[] = { 188static struct intc_sense_reg sense_registers[] __initdata = {
189 { 0xa414001c, 16, 2, /* ICR1 */ 189 { 0xa414001c, 16, 2, /* ICR1 */
190 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 190 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
191}; 191};
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index 6a04cc5f5aca..32f4f59a837b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -51,3 +51,7 @@ static int __init sh7770_devices_setup(void)
51 ARRAY_SIZE(sh7770_devices)); 51 ARRAY_SIZE(sh7770_devices));
52} 52}
53__initcall(sh7770_devices_setup); 53__initcall(sh7770_devices_setup);
54
55void __init plat_irq_setup(void)
56{
57}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index a4127ec15203..e8fd33ff0605 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -10,6 +10,7 @@
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <linux/io.h>
13#include <asm/sci.h> 14#include <asm/sci.h>
14 15
15static struct resource rtc_resources[] = { 16static struct resource rtc_resources[] = {
@@ -114,7 +115,7 @@ enum {
114 PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO, 115 PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO,
115}; 116};
116 117
117static struct intc_vect vectors[] = { 118static struct intc_vect vectors[] __initdata = {
118 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), 119 INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
119 INTC_VECT(RTC_CUI, 0x4c0), 120 INTC_VECT(RTC_CUI, 0x4c0),
120 INTC_VECT(WDT, 0x560), 121 INTC_VECT(WDT, 0x560),
@@ -150,7 +151,7 @@ static struct intc_vect vectors[] = {
150 INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), 151 INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
151}; 152};
152 153
153static struct intc_group groups[] = { 154static struct intc_group groups[] __initdata = {
154 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), 155 INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
155 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), 156 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
156 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, 157 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
@@ -167,12 +168,12 @@ static struct intc_group groups[] = {
167 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), 168 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
168}; 169};
169 170
170static struct intc_prio priorities[] = { 171static struct intc_prio priorities[] __initdata = {
171 INTC_PRIO(SCIF0, 3), 172 INTC_PRIO(SCIF0, 3),
172 INTC_PRIO(SCIF1, 3), 173 INTC_PRIO(SCIF1, 3),
173}; 174};
174 175
175static struct intc_mask_reg mask_registers[] = { 176static struct intc_mask_reg mask_registers[] __initdata = {
176 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ 177 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
177 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, 178 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL,
178 SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, 179 SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
@@ -180,16 +181,18 @@ static struct intc_mask_reg mask_registers[] = {
180 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, 181 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
181}; 182};
182 183
183static struct intc_prio_reg prio_registers[] = { 184static struct intc_prio_reg prio_registers[] __initdata = {
184 { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, 185 { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
185 { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, 186 TMU2, TMU2_TICPI } },
186 { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, 187 { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
187 { 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, 188 { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
188 { 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } }, 189 { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } },
189 { 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, 190 { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
190 PCIINTD, PCIC5 } }, 191 PCISERR, PCIINTA, } },
191 { 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, 192 { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
192 { 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, 193 PCIINTD, PCIC5 } },
194 { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } },
195 { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },
193}; 196};
194 197
195static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, 198static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities,
@@ -197,24 +200,24 @@ static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities,
197 200
198/* Support for external interrupt pins in IRQ mode */ 201/* Support for external interrupt pins in IRQ mode */
199 202
200static struct intc_vect irq_vectors[] = { 203static struct intc_vect irq_vectors[] __initdata = {
201 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), 204 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
202 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), 205 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
203 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), 206 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
204 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), 207 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
205}; 208};
206 209
207static struct intc_mask_reg irq_mask_registers[] = { 210static struct intc_mask_reg irq_mask_registers[] __initdata = {
208 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ 211 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
209 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, 212 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
210}; 213};
211 214
212static struct intc_prio_reg irq_prio_registers[] = { 215static struct intc_prio_reg irq_prio_registers[] __initdata = {
213 { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, 216 { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
214 IRQ4, IRQ5, IRQ6, IRQ7 } }, 217 IRQ4, IRQ5, IRQ6, IRQ7 } },
215}; 218};
216 219
217static struct intc_sense_reg irq_sense_registers[] = { 220static struct intc_sense_reg irq_sense_registers[] __initdata = {
218 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, 221 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
219 IRQ4, IRQ5, IRQ6, IRQ7 } }, 222 IRQ4, IRQ5, IRQ6, IRQ7 } },
220}; 223};
@@ -225,7 +228,7 @@ static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors,
225 228
226/* External interrupt pins in IRL mode */ 229/* External interrupt pins in IRL mode */
227 230
228static struct intc_vect irl_vectors[] = { 231static struct intc_vect irl_vectors[] __initdata = {
229 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), 232 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
230 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), 233 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
231 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), 234 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
@@ -236,16 +239,16 @@ static struct intc_vect irl_vectors[] = {
236 INTC_VECT(IRL_HHHL, 0x3c0), 239 INTC_VECT(IRL_HHHL, 0x3c0),
237}; 240};
238 241
239static struct intc_mask_reg irl3210_mask_registers[] = { 242static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
240 { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ 243 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
241 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 244 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
242 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 245 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
243 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, 246 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
244 IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, 247 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
245}; 248};
246 249
247static struct intc_mask_reg irl7654_mask_registers[] = { 250static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
248 { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ 251 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
249 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, 253 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
251 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, 254 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
@@ -259,8 +262,28 @@ static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
259static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, 262static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
260 NULL, NULL, irl3210_mask_registers, NULL, NULL); 263 NULL, NULL, irl3210_mask_registers, NULL, NULL);
261 264
265#define INTC_ICR0 0xffd00000
266#define INTC_INTMSK0 0xffd00044
267#define INTC_INTMSK1 0xffd00048
268#define INTC_INTMSK2 0xffd40080
269#define INTC_INTMSKCLR1 0xffd00068
270#define INTC_INTMSKCLR2 0xffd40084
271
262void __init plat_irq_setup(void) 272void __init plat_irq_setup(void)
263{ 273{
274 /* disable IRQ7-0 */
275 ctrl_outl(0xff000000, INTC_INTMSK0);
276
277 /* disable IRL3-0 + IRL7-4 */
278 ctrl_outl(0xc0000000, INTC_INTMSK1);
279 ctrl_outl(0xfffefffe, INTC_INTMSK2);
280
281 /* select IRL mode for IRL3-0 + IRL7-4 */
282 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
283
284 /* disable holding function, ie enable "SH-4 Mode" */
285 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
286
264 register_intc_controller(&intc_desc); 287 register_intc_controller(&intc_desc);
265} 288}
266 289
@@ -268,12 +291,28 @@ void __init plat_irq_setup_pins(int mode)
268{ 291{
269 switch (mode) { 292 switch (mode) {
270 case IRQ_MODE_IRQ: 293 case IRQ_MODE_IRQ:
294 /* select IRQ mode for IRL3-0 + IRL7-4 */
295 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
271 register_intc_controller(&intc_irq_desc); 296 register_intc_controller(&intc_irq_desc);
272 break; 297 break;
273 case IRQ_MODE_IRL7654: 298 case IRQ_MODE_IRL7654:
274 register_intc_controller(&intc_irl7654_desc); 299 /* enable IRL7-4 but don't provide any masking */
300 ctrl_outl(0x40000000, INTC_INTMSKCLR1);
301 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
275 break; 302 break;
276 case IRQ_MODE_IRL3210: 303 case IRQ_MODE_IRL3210:
304 /* enable IRL0-3 but don't provide any masking */
305 ctrl_outl(0x80000000, INTC_INTMSKCLR1);
306 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
307 break;
308 case IRQ_MODE_IRL7654_MASK:
309 /* enable IRL7-4 and mask using cpu intc controller */
310 ctrl_outl(0x40000000, INTC_INTMSKCLR1);
311 register_intc_controller(&intc_irl7654_desc);
312 break;
313 case IRQ_MODE_IRL3210_MASK:
314 /* enable IRL0-3 and mask using cpu intc controller */
315 ctrl_outl(0x80000000, INTC_INTMSKCLR1);
277 register_intc_controller(&intc_irl3210_desc); 316 register_intc_controller(&intc_irl3210_desc);
278 break; 317 break;
279 default: 318 default:
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index cf047562e43f..39b215d6cee5 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -10,6 +10,9 @@
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <linux/io.h>
14#include <linux/mm.h>
15#include <asm/mmzone.h>
13#include <asm/sci.h> 16#include <asm/sci.h>
14 17
15static struct plat_sci_port sci_platform_data[] = { 18static struct plat_sci_port sci_platform_data[] = {
@@ -72,46 +75,281 @@ static int __init sh7785_devices_setup(void)
72} 75}
73__initcall(sh7785_devices_setup); 76__initcall(sh7785_devices_setup);
74 77
75static struct intc2_data intc2_irq_table[] = { 78enum {
76 { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ 79 UNUSED = 0,
77 80
78 { 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */ 81 /* interrupt sources */
79 { 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */ 82
80 { 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */ 83 IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
81 { 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */ 84 IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
82 85 IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
83 { 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */ 86 IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
84 { 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */ 87
85 { 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */ 88 IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
86 { 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */ 89 IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
87 90 IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
88 { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */ 91 IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
89 { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */ 92
90 { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */ 93 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
91 { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */ 94 WDT,
92 { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */ 95 TMU0, TMU1, TMU2, TMU2_TICPI,
93 96 HUDI,
94 { 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */ 97 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
95 { 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */ 98 DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
96 { 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */ 99 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
97 { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ 100 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
101 DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
102 DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
103 HSPI,
104 SCIF2, SCIF3, SCIF4, SCIF5,
105 PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
106 PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
107 SIOF,
108 MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
109 DU,
110 GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI,
111 TMU3, TMU4, TMU5,
112 SSI0, SSI1,
113 HAC0, HAC1,
114 FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1,
115 GPIOI0, GPIOI1, GPIOI2, GPIOI3,
116
117 /* interrupt groups */
118
119 TMU012, DMAC0, SCIF0, SCIF1, DMAC1,
120 PCIC5, MMCIF, GDTA, TMU345, FLCTL, GPIO
98}; 121};
99 122
100static struct intc2_desc intc2_irq_desc __read_mostly = { 123static struct intc_vect vectors[] __initdata = {
101 .prio_base = 0xffd40000, 124 INTC_VECT(WDT, 0x560),
102 .msk_base = 0xffd40038, 125 INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
103 .mskclr_base = 0xffd4003c, 126 INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
127 INTC_VECT(HUDI, 0x600),
128 INTC_VECT(DMAC0_DMINT0, 0x620), INTC_VECT(DMAC0_DMINT1, 0x640),
129 INTC_VECT(DMAC0_DMINT2, 0x660), INTC_VECT(DMAC0_DMINT3, 0x680),
130 INTC_VECT(DMAC0_DMINT4, 0x6a0), INTC_VECT(DMAC0_DMINT5, 0x6c0),
131 INTC_VECT(DMAC0_DMAE, 0x6e0),
132 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
133 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
134 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
135 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
136 INTC_VECT(DMAC1_DMINT6, 0x880), INTC_VECT(DMAC1_DMINT7, 0x8a0),
137 INTC_VECT(DMAC1_DMINT8, 0x8c0), INTC_VECT(DMAC1_DMINT9, 0x8e0),
138 INTC_VECT(DMAC1_DMINT10, 0x900), INTC_VECT(DMAC1_DMINT11, 0x920),
139 INTC_VECT(DMAC1_DMAE, 0x940),
140 INTC_VECT(HSPI, 0x960),
141 INTC_VECT(SCIF2, 0x980), INTC_VECT(SCIF3, 0x9a0),
142 INTC_VECT(SCIF4, 0x9c0), INTC_VECT(SCIF5, 0x9e0),
143 INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
144 INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
145 INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
146 INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
147 INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
148 INTC_VECT(SIOF, 0xc00),
149 INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
150 INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
151 INTC_VECT(DU, 0xd80),
152 INTC_VECT(GDTA_GACLI, 0xda0), INTC_VECT(GDTA_GAMCI, 0xdc0),
153 INTC_VECT(GDTA_GAERI, 0xde0),
154 INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
155 INTC_VECT(TMU5, 0xe40),
156 INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
157 INTC_VECT(HAC0, 0xec0), INTC_VECT(HAC1, 0xee0),
158 INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20),
159 INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60),
160 INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0),
161 INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
162};
104 163
105 .intc2_data = intc2_irq_table, 164static struct intc_group groups[] __initdata = {
106 .nr_irqs = ARRAY_SIZE(intc2_irq_table), 165 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
166 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
167 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
168 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
169 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
170 INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
171 DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE),
172 INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
173 INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
174 INTC_GROUP(GDTA, GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI),
175 INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
176 INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND,
177 FLCTL_FLTRQ0, FLCTL_FLTRQ1),
178 INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
179};
107 180
108 .chip = { 181static struct intc_prio priorities[] __initdata = {
109 .name = "INTC2-sh7785", 182 INTC_PRIO(SCIF0, 3),
110 }, 183 INTC_PRIO(SCIF1, 3),
184 INTC_PRIO(SCIF2, 3),
185 INTC_PRIO(SCIF3, 3),
186 INTC_PRIO(SCIF4, 3),
187 INTC_PRIO(SCIF5, 3),
188};
189
190static struct intc_mask_reg mask_registers[] __initdata = {
191 { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
192 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
193
194 { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
195 { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
196 IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
197 IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
198 IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
199 IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
200 IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
201 IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
202 IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
203
204 { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
205 { 0, 0, 0, GDTA, DU, SSI0, SSI1, GPIO,
206 FLCTL, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
207 PCIINTA, PCISERR, HAC1, HAC0, DMAC1, DMAC0, HUDI, WDT,
208 SCIF5, SCIF4, SCIF3, SCIF2, SCIF1, SCIF0, TMU345, TMU012 } },
209};
210
211static struct intc_prio_reg prio_registers[] __initdata = {
212 { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
213 IRQ4, IRQ5, IRQ6, IRQ7 } },
214 { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
215 TMU2, TMU2_TICPI } },
216 { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, } },
217 { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1,
218 SCIF2, SCIF3 } },
219 { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { SCIF4, SCIF5, WDT, } },
220 { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { HUDI, DMAC0, DMAC1, } },
221 { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { HAC0, HAC1,
222 PCISERR, PCIINTA } },
223 { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { PCIINTB, PCIINTC,
224 PCIINTD, PCIC5 } },
225 { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SIOF, HSPI, MMCIF, } },
226 { 0xffd40020, 0, 32, 8, /* INT2PRI8 */ { FLCTL, GPIO, SSI0, SSI1, } },
227 { 0xffd40024, 0, 32, 8, /* INT2PRI9 */ { DU, GDTA, } },
111}; 228};
112 229
230static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups, priorities,
231 mask_registers, prio_registers, NULL);
232
233/* Support for external interrupt pins in IRQ mode */
234
235static struct intc_vect vectors_irq0123[] __initdata = {
236 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
237 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
238};
239
240static struct intc_vect vectors_irq4567[] __initdata = {
241 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
242 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
243};
244
245static struct intc_sense_reg sense_registers[] __initdata = {
246 { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
247 IRQ4, IRQ5, IRQ6, IRQ7 } },
248};
249
250static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123,
251 NULL, NULL, mask_registers, prio_registers,
252 sense_registers);
253
254static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567,
255 NULL, NULL, mask_registers, prio_registers,
256 sense_registers);
257
258/* External interrupt pins in IRL mode */
259
260static struct intc_vect vectors_irl0123[] __initdata = {
261 INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
262 INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
263 INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
264 INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
265 INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
266 INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
267 INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
268 INTC_VECT(IRL0_HHHL, 0x3c0),
269};
270
271static struct intc_vect vectors_irl4567[] __initdata = {
272 INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20),
273 INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60),
274 INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0),
275 INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0),
276 INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20),
277 INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60),
278 INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0),
279 INTC_VECT(IRL4_HHHL, 0xcc0),
280};
281
282static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123,
283 NULL, NULL, mask_registers, NULL, NULL);
284
285static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567,
286 NULL, NULL, mask_registers, NULL, NULL);
287
288#define INTC_ICR0 0xffd00000
289#define INTC_INTMSK0 0xffd00044
290#define INTC_INTMSK1 0xffd00048
291#define INTC_INTMSK2 0xffd40080
292#define INTC_INTMSKCLR1 0xffd00068
293#define INTC_INTMSKCLR2 0xffd40084
294
113void __init plat_irq_setup(void) 295void __init plat_irq_setup(void)
114{ 296{
115 register_intc2_controller(&intc2_irq_desc); 297 /* disable IRQ3-0 + IRQ7-4 */
298 ctrl_outl(0xff000000, INTC_INTMSK0);
299
300 /* disable IRL3-0 + IRL7-4 */
301 ctrl_outl(0xc0000000, INTC_INTMSK1);
302 ctrl_outl(0xfffefffe, INTC_INTMSK2);
303
304 /* select IRL mode for IRL3-0 + IRL7-4 */
305 ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
306
307 /* disable holding function, ie enable "SH-4 Mode" */
308 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
309
310 register_intc_controller(&intc_desc);
311}
312
313void __init plat_irq_setup_pins(int mode)
314{
315 switch (mode) {
316 case IRQ_MODE_IRQ7654:
317 /* select IRQ mode for IRL7-4 */
318 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
319 register_intc_controller(&intc_desc_irq4567);
320 break;
321 case IRQ_MODE_IRQ3210:
322 /* select IRQ mode for IRL3-0 */
323 ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
324 register_intc_controller(&intc_desc_irq0123);
325 break;
326 case IRQ_MODE_IRL7654:
327 /* enable IRL7-4 but don't provide any masking */
328 ctrl_outl(0x40000000, INTC_INTMSKCLR1);
329 ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
330 break;
331 case IRQ_MODE_IRL3210:
332 /* enable IRL0-3 but don't provide any masking */
333 ctrl_outl(0x80000000, INTC_INTMSKCLR1);
334 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
335 break;
336 case IRQ_MODE_IRL7654_MASK:
337 /* enable IRL7-4 and mask using cpu intc controller */
338 ctrl_outl(0x40000000, INTC_INTMSKCLR1);
339 register_intc_controller(&intc_desc_irl4567);
340 break;
341 case IRQ_MODE_IRL3210_MASK:
342 /* enable IRL0-3 and mask using cpu intc controller */
343 ctrl_outl(0x80000000, INTC_INTMSKCLR1);
344 register_intc_controller(&intc_desc_irl0123);
345 break;
346 default:
347 BUG();
348 }
116} 349}
117 350
351void __init plat_mem_setup(void)
352{
353 /* Register the URAM space as Node 1 */
354 setup_bootmem_node(1, 0xe55f0000, 0xe5610000);
355}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 704c064f70dc..c6cdd7e3b049 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -11,6 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/serial.h> 12#include <linux/serial.h>
13#include <linux/io.h> 13#include <linux/io.h>
14#include <asm/mmzone.h>
14#include <asm/sci.h> 15#include <asm/sci.h>
15 16
16static struct plat_sci_port sci_platform_data[] = { 17static struct plat_sci_port sci_platform_data[] = {
@@ -58,28 +59,229 @@ static int __init shx3_devices_setup(void)
58} 59}
59__initcall(shx3_devices_setup); 60__initcall(shx3_devices_setup);
60 61
61static struct intc2_data intc2_irq_table[] = { 62enum {
62 { 16, 0, 0, 0, 1, 2 }, /* TMU0 */ 63 UNUSED = 0,
63 { 40, 4, 0, 0x20, 0, 3 }, /* SCIF0 ERI */ 64
64 { 41, 4, 0, 0x20, 1, 3 }, /* SCIF0 RXI */ 65 /* interrupt sources */
65 { 42, 4, 0, 0x20, 2, 3 }, /* SCIF0 BRI */ 66 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
66 { 43, 4, 0, 0x20, 3, 3 }, /* SCIF0 TXI */ 67 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
68 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
69 IRL_HHLL, IRL_HHLH, IRL_HHHL,
70 IRQ0, IRQ1, IRQ2, IRQ3,
71 HUDII,
72 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
73 PCII0, PCII1, PCII2, PCII3, PCII4,
74 PCII5, PCII6, PCII7, PCII8, PCII9,
75 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
76 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
77 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
78 SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
79 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
80 DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
81 DU,
82 DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
83 DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
84 IIC, VIN0, VIN1, VCORE0, ATAPI,
85 DTU0_TEND, DTU0_AE, DTU0_TMISS,
86 DTU1_TEND, DTU1_AE, DTU1_TMISS,
87 DTU2_TEND, DTU2_AE, DTU2_TMISS,
88 DTU3_TEND, DTU3_AE, DTU3_TMISS,
89 FE0, FE1,
90 GPIO0, GPIO1, GPIO2, GPIO3,
91 PAM, IRM,
92 INTICI0, INTICI1, INTICI2, INTICI3,
93 INTICI4, INTICI5, INTICI6, INTICI7,
94
95 /* interrupt groups */
96 IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
97 DMAC0, DMAC1, DTU0, DTU1, DTU2, DTU3,
98};
99
100static struct intc_vect vectors[] __initdata = {
101 INTC_VECT(HUDII, 0x3e0),
102 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
103 INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
104 INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
105 INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
106 INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
107 INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
108 INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
109 INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
110 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
111 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
112 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
113 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
114 INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820),
115 INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860),
116 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
117 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
118 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
119 INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
120 INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
121 INTC_VECT(DMAC0_DMAE, 0x9c0),
122 INTC_VECT(DU, 0x9e0),
123 INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
124 INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
125 INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
126 INTC_VECT(DMAC1_DMAE, 0xac0),
127 INTC_VECT(IIC, 0xae0),
128 INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
129 INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
130 INTC_VECT(DTU0_TEND, 0xc00), INTC_VECT(DTU0_AE, 0xc20),
131 INTC_VECT(DTU0_TMISS, 0xc40),
132 INTC_VECT(DTU1_TEND, 0xc60), INTC_VECT(DTU1_AE, 0xc80),
133 INTC_VECT(DTU1_TMISS, 0xca0),
134 INTC_VECT(DTU2_TEND, 0xcc0), INTC_VECT(DTU2_AE, 0xce0),
135 INTC_VECT(DTU2_TMISS, 0xd00),
136 INTC_VECT(DTU3_TEND, 0xd20), INTC_VECT(DTU3_AE, 0xd40),
137 INTC_VECT(DTU3_TMISS, 0xd60),
138 INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
139 INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
140 INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
141 INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
142 INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
143 INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
144 INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
145 INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
67}; 146};
68 147
69static struct intc2_desc intc2_irq_desc __read_mostly = { 148static struct intc_group groups[] __initdata = {
70 .prio_base = 0xfe410000, 149 INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
71 .msk_base = 0xfe410820, 150 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
72 .mskclr_base = 0xfe410850, 151 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
152 IRL_HHLL, IRL_HHLH, IRL_HHHL),
153 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
154 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
155 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
156 INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
157 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
158 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
159 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
160 INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
161 DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
162 INTC_GROUP(DTU0, DTU0_TEND, DTU0_AE, DTU0_TMISS),
163 INTC_GROUP(DTU1, DTU1_TEND, DTU1_AE, DTU1_TMISS),
164 INTC_GROUP(DTU2, DTU2_TEND, DTU2_AE, DTU2_TMISS),
165 INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS),
166};
73 167
74 .intc2_data = intc2_irq_table, 168static struct intc_prio priorities[] __initdata = {
75 .nr_irqs = ARRAY_SIZE(intc2_irq_table), 169 INTC_PRIO(SCIF0, 3),
170 INTC_PRIO(SCIF1, 3),
171 INTC_PRIO(SCIF2, 3),
172 INTC_PRIO(SCIF3, 3),
173};
76 174
77 .chip = { 175static struct intc_mask_reg mask_registers[] __initdata = {
78 .name = "INTC2-SHX3", 176 { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
79 }, 177 { IRQ0, IRQ1, IRQ2, IRQ3 } },
178 { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
179 { IRL } },
180 { 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
181 { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
182 DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
183 0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
184 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, } },
185 { 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
186 { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
187 PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
188 PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
189 DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
190 DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
191 DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 } },
192 { 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
193 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194 SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
195 SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
196 SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
197 SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } },
198};
199
200static struct intc_prio_reg prio_registers[] __initdata = {
201 { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
202
203 { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
204 TMU3, TMU2, TMU1, TMU0 } },
205 { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
206 SCIF3, SCIF2,
207 SCIF1, SCIF0 } },
208 { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
209 PCII56789, PCII4,
210 PCII3, PCII2,
211 PCII1, PCII0 } },
212 { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
213 VIN1, VIN0, IIC, DU} },
214 { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
215 GPIO2, GPIO1, GPIO0, IRM } },
216 { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
217 { INTICI7, INTICI6, INTICI5, INTICI4,
218 INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
219};
220
221static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups, priorities,
222 mask_registers, prio_registers, NULL);
223
224/* Support for external interrupt pins in IRQ mode */
225static struct intc_vect vectors_irq[] __initdata = {
226 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
227 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
228};
229
230static struct intc_sense_reg sense_registers[] __initdata = {
231 { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
80}; 232};
81 233
234static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
235 priorities, mask_registers, prio_registers,
236 sense_registers);
237
238/* External interrupt pins in IRL mode */
239static struct intc_vect vectors_irl[] __initdata = {
240 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
241 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
242 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
243 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
244 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
245 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
246 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
247 INTC_VECT(IRL_HHHL, 0x3c0),
248};
249
250static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
251 priorities, mask_registers, prio_registers, NULL);
252
253void __init plat_irq_setup_pins(int mode)
254{
255 switch (mode) {
256 case IRQ_MODE_IRQ:
257 register_intc_controller(&intc_desc_irq);
258 break;
259 case IRQ_MODE_IRL3210:
260 register_intc_controller(&intc_desc_irl);
261 break;
262 default:
263 BUG();
264 }
265}
266
82void __init plat_irq_setup(void) 267void __init plat_irq_setup(void)
83{ 268{
84 register_intc2_controller(&intc2_irq_desc); 269 register_intc_controller(&intc_desc);
270}
271
272void __init plat_mem_setup(void)
273{
274 unsigned int nid = 1;
275
276 /* Register CPU#0 URAM space as Node 1 */
277 setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
278
279#if 0
280 /* XXX: Not yet.. */
281 setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
282 setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
283 setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
284#endif
285
286 setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
85} 287}
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
new file mode 100644
index 000000000000..e5e06845fa43
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -0,0 +1,120 @@
1/*
2 * SH-X3 SMP
3 *
4 * Copyright (C) 2007 Paul Mundt
5 * Copyright (C) 2007 Magnus Damm
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/init.h>
12#include <linux/cpumask.h>
13#include <linux/smp.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16
17void __init plat_smp_setup(void)
18{
19 unsigned int cpu = 0;
20 int i, num;
21
22 cpus_clear(cpu_possible_map);
23 cpu_set(cpu, cpu_possible_map);
24
25 __cpu_number_map[0] = 0;
26 __cpu_logical_map[0] = 0;
27
28 /*
29 * Do this stupidly for now.. we don't have an easy way to probe
30 * for the total number of cores.
31 */
32 for (i = 1, num = 0; i < NR_CPUS; i++) {
33 cpu_set(i, cpu_possible_map);
34 __cpu_number_map[i] = ++num;
35 __cpu_logical_map[num] = i;
36 }
37
38 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
39}
40
41void __init plat_prepare_cpus(unsigned int max_cpus)
42{
43}
44
45#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
46#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
47
48#define STBCR_MSTP 0x00000001
49#define STBCR_RESET 0x00000002
50#define STBCR_LTSLP 0x80000000
51
52#define STBCR_AP_VAL (STBCR_RESET | STBCR_LTSLP)
53
54void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
55{
56 ctrl_outl(entry_point, RESET_REG(cpu));
57
58 if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
59 ctrl_outl(STBCR_MSTP, STBCR_REG(cpu));
60
61 while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
62 ;
63
64 /* Start up secondary processor by sending a reset */
65 ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu));
66}
67
68int plat_smp_processor_id(void)
69{
70 return ctrl_inl(0xff000048); /* CPIDR */
71}
72
73void plat_send_ipi(unsigned int cpu, unsigned int message)
74{
75 unsigned long addr = 0xfe410070 + (cpu * 4);
76
77 BUG_ON(cpu >= 4);
78 BUG_ON(message >= SMP_MSG_NR);
79
80 ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
81}
82
83struct ipi_data {
84 void (*handler)(void *);
85 void *arg;
86 unsigned int message;
87};
88
89static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
90{
91 struct ipi_data *id = arg;
92 unsigned int cpu = hard_smp_processor_id();
93 unsigned int offs = 4 * cpu;
94 unsigned int x;
95
96 x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
97 x &= (1 << (id->message << 2));
98 ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
99
100 id->handler(id->arg);
101
102 return IRQ_HANDLED;
103}
104
105static struct ipi_data ipi_handlers[SMP_MSG_NR];
106
107int plat_register_ipi_handler(unsigned int message,
108 void (*handler)(void *), void *arg)
109{
110 struct ipi_data *id = &ipi_handlers[message];
111
112 BUG_ON(SMP_MSG_NR >= 8);
113 BUG_ON(message >= SMP_MSG_NR);
114
115 id->handler = handler;
116 id->arg = arg;
117 id->message = message;
118
119 return request_irq(104 + message, ipi_interrupt_handler, 0, "IPI", id);
120}
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index 71d1c427b907..e0590ffebd73 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -77,8 +77,6 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
77 77
78static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) 78static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
79{ 79{
80 printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n");
81
82 if (!cpu_online(policy->cpu)) 80 if (!cpu_online(policy->cpu))
83 return -ENODEV; 81 return -ENODEV;
84 82
@@ -143,6 +141,7 @@ static struct cpufreq_driver sh_cpufreq_driver = {
143 141
144static int __init sh_cpufreq_module_init(void) 142static int __init sh_cpufreq_module_init(void)
145{ 143{
144 printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n");
146 return cpufreq_register_driver(&sh_cpufreq_driver); 145 return cpufreq_register_driver(&sh_cpufreq_driver);
147} 146}
148 147
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 80b637c30203..2f30977558ad 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka 4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2002 M. R. Brown 5 * Copyright (C) 2002 M. R. Brown
6 * Copyright (C) 2004 - 2006 Paul Mundt 6 * Copyright (C) 2004 - 2007 Paul Mundt
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 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 9 * License. See the file "COPYING" in the main directory of this archive
@@ -13,6 +13,7 @@
13#include <linux/tty.h> 13#include <linux/tty.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/delay.h>
16 17
17#ifdef CONFIG_SH_STANDARD_BIOS 18#ifdef CONFIG_SH_STANDARD_BIOS
18#include <asm/sh_bios.h> 19#include <asm/sh_bios.h>
@@ -62,6 +63,16 @@ static struct console bios_console = {
62#include <linux/serial_core.h> 63#include <linux/serial_core.h>
63#include "../../../drivers/serial/sh-sci.h" 64#include "../../../drivers/serial/sh-sci.h"
64 65
66#if defined(CONFIG_CPU_SUBTYPE_SH7720)
67#define EPK_SCSMR_VALUE 0x000
68#define EPK_SCBRR_VALUE 0x00C
69#define EPK_FIFO_SIZE 64
70#define EPK_FIFO_BITS (0x7f00 >> 8)
71#else
72#define EPK_FIFO_SIZE 16
73#define EPK_FIFO_BITS (0x1f00 >> 8)
74#endif
75
65static struct uart_port scif_port = { 76static struct uart_port scif_port = {
66 .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT, 77 .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT,
67 .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, 78 .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
@@ -69,7 +80,7 @@ static struct uart_port scif_port = {
69 80
70static void scif_sercon_putc(int c) 81static void scif_sercon_putc(int c)
71{ 82{
72 while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16)) 83 while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE))
73 ; 84 ;
74 85
75 sci_out(&scif_port, SCxTDR, c); 86 sci_out(&scif_port, SCxTDR, c);
@@ -105,7 +116,22 @@ static struct console scif_console = {
105 .index = -1, 116 .index = -1,
106}; 117};
107 118
108#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) 119#if !defined(CONFIG_SH_STANDARD_BIOS)
120#if defined(CONFIG_CPU_SUBTYPE_SH7720)
121static void scif_sercon_init(char *s)
122{
123 sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */
124 sci_out(&scif_port, SCFCR, 0x4006); /* reset */
125 sci_out(&scif_port, SCSCR, 0x0000); /* select internal clock */
126 sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE);
127 sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE);
128
129 mdelay(1); /* wait 1-bit time */
130
131 sci_out(&scif_port, SCFCR, 0x0030); /* TTRG=b'11 */
132 sci_out(&scif_port, SCSCR, 0x0030); /* TE, RE */
133}
134#elif defined(CONFIG_CPU_SH4)
109#define DEFAULT_BAUD 115200 135#define DEFAULT_BAUD 115200
110/* 136/*
111 * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 137 * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
@@ -146,7 +172,8 @@ static void scif_sercon_init(char *s)
146 ctrl_outw(0, scif_port.mapbase + 36); 172 ctrl_outw(0, scif_port.mapbase + 36);
147 ctrl_outw(0x30, scif_port.mapbase + 8); 173 ctrl_outw(0x30, scif_port.mapbase + 8);
148} 174}
149#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */ 175#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */
176#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */
150#endif /* CONFIG_EARLY_SCIF_CONSOLE */ 177#endif /* CONFIG_EARLY_SCIF_CONSOLE */
151 178
152/* 179/*
@@ -163,17 +190,12 @@ static struct console *early_console =
163#endif 190#endif
164 ; 191 ;
165 192
166static int __initdata keep_early; 193static int __init setup_early_printk(char *buf)
167static int early_console_initialized;
168
169int __init setup_early_printk(char *buf)
170{ 194{
171 if (!buf) 195 int keep_early = 0;
172 return 0;
173 196
174 if (early_console_initialized) 197 if (!buf)
175 return 0; 198 return 0;
176 early_console_initialized = 1;
177 199
178 if (strstr(buf, "keep")) 200 if (strstr(buf, "keep"))
179 keep_early = 1; 201 keep_early = 1;
@@ -186,7 +208,8 @@ int __init setup_early_printk(char *buf)
186 if (!strncmp(buf, "serial", 6)) { 208 if (!strncmp(buf, "serial", 6)) {
187 early_console = &scif_console; 209 early_console = &scif_console;
188 210
189#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) 211#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720)) && \
212 !defined(CONFIG_SH_STANDARD_BIOS)
190 scif_sercon_init(buf + 6); 213 scif_sercon_init(buf + 6);
191#endif 214#endif
192 } 215 }
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index b46728027195..e0317ed080c3 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -176,7 +176,7 @@ work_notifysig:
176 jmp @r1 176 jmp @r1
177 lds r0, pr 177 lds r0, pr
178work_resched: 178work_resched:
179#ifndef CONFIG_PREEMPT 179#if defined(CONFIG_GUSA) && !defined(CONFIG_PREEMPT)
180 ! gUSA handling 180 ! gUSA handling
181 mov.l @(OFF_SP,r15), r0 ! get user space stack pointer 181 mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
182 mov r0, r1 182 mov r0, r1
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index 0bccc0ca5a0f..3338239717f1 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -54,8 +54,8 @@ ENTRY(_stext)
54 mov.l 1f, r0 ! MD=1, RB=0, BL=0, IMASK=0xF 54 mov.l 1f, r0 ! MD=1, RB=0, BL=0, IMASK=0xF
55 ldc r0, sr 55 ldc r0, sr
56 ! Initialize global interrupt mask 56 ! Initialize global interrupt mask
57 mov #0, r0
58#ifdef CONFIG_CPU_HAS_SR_RB 57#ifdef CONFIG_CPU_HAS_SR_RB
58 mov #0, r0
59 ldc r0, r6_bank 59 ldc r0, r6_bank
60#endif 60#endif
61 61
@@ -72,15 +72,18 @@ ENTRY(_stext)
72 ! 72 !
73 mov.l 2f, r0 73 mov.l 2f, r0
74 mov r0, r15 ! Set initial r15 (stack pointer) 74 mov r0, r15 ! Set initial r15 (stack pointer)
75 mov #(THREAD_SIZE >> 10), r1
76 shll8 r1 ! r1 = THREAD_SIZE
77 shll2 r1
78 sub r1, r0 !
79#ifdef CONFIG_CPU_HAS_SR_RB 75#ifdef CONFIG_CPU_HAS_SR_RB
76 mov.l 7f, r0
80 ldc r0, r7_bank ! ... and initial thread_info 77 ldc r0, r7_bank ! ... and initial thread_info
81#endif 78#endif
82 79
83 ! Clear BSS area 80 ! Clear BSS area
81#ifdef CONFIG_SMP
82 mov.l 3f, r0
83 cmp/eq #0, r0 ! skip clear if set to zero
84 bt 10f
85#endif
86
84 mov.l 3f, r1 87 mov.l 3f, r1
85 add #4, r1 88 add #4, r1
86 mov.l 4f, r2 89 mov.l 4f, r2
@@ -89,13 +92,14 @@ ENTRY(_stext)
89 bf/s 9b ! while (r1 < r2) 92 bf/s 9b ! while (r1 < r2)
90 mov.l r0,@-r2 93 mov.l r0,@-r2
91 94
9510:
92 ! Additional CPU initialization 96 ! Additional CPU initialization
93 mov.l 6f, r0 97 mov.l 6f, r0
94 jsr @r0 98 jsr @r0
95 nop 99 nop
96 100
97 SYNCO() ! Wait for pending instructions.. 101 SYNCO() ! Wait for pending instructions..
98 102
99 ! Start kernel 103 ! Start kernel
100 mov.l 5f, r0 104 mov.l 5f, r0
101 jmp @r0 105 jmp @r0
@@ -107,8 +111,10 @@ ENTRY(_stext)
107#else 111#else
1081: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF 1121: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
109#endif 113#endif
114ENTRY(stack_start)
1102: .long init_thread_union+THREAD_SIZE 1152: .long init_thread_union+THREAD_SIZE
1113: .long __bss_start 1163: .long __bss_start
1124: .long _end 1174: .long _end
1135: .long start_kernel 1185: .long start_kernel
1146: .long sh_cpu_init 1196: .long sh_cpu_init
1207: .long init_thread_union
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index edd1ec214e6d..2fdc700dfd6e 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -150,13 +150,6 @@ struct kgdb_regs trap_registers;
150char kgdb_in_gdb_mode; 150char kgdb_in_gdb_mode;
151char in_nmi; /* Set during NMI to prevent reentry */ 151char in_nmi; /* Set during NMI to prevent reentry */
152int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ 152int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
153int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */
154
155/* Exposed for user access */
156struct task_struct *kgdb_current;
157unsigned int kgdb_g_imask;
158int kgdb_trapa_val;
159int kgdb_excode;
160 153
161/* Default values for SCI (can override via kernel args in setup.c) */ 154/* Default values for SCI (can override via kernel args in setup.c) */
162#ifndef CONFIG_KGDB_DEFPORT 155#ifndef CONFIG_KGDB_DEFPORT
@@ -616,7 +609,7 @@ static short *get_step_address(void)
616 else 609 else
617 addr = trap_registers.pc + 2; 610 addr = trap_registers.pc + 2;
618 611
619 kgdb_flush_icache_range(addr, addr + 2); 612 flush_icache_range(addr, addr + 2);
620 return (short *) addr; 613 return (short *) addr;
621} 614}
622 615
@@ -639,8 +632,7 @@ static void do_single_step(void)
639 *addr = STEP_OPCODE; 632 *addr = STEP_OPCODE;
640 633
641 /* Flush and return */ 634 /* Flush and return */
642 kgdb_flush_icache_range((long) addr, (long) addr + 2); 635 flush_icache_range((long) addr, (long) addr + 2);
643 return;
644} 636}
645 637
646/* Undo a single step */ 638/* Undo a single step */
@@ -650,7 +642,7 @@ static void undo_single_step(void)
650 /* Use stepped_address in case we stopped elsewhere */ 642 /* Use stepped_address in case we stopped elsewhere */
651 if (stepped_opcode != 0) { 643 if (stepped_opcode != 0) {
652 *(short*)stepped_address = stepped_opcode; 644 *(short*)stepped_address = stepped_opcode;
653 kgdb_flush_icache_range(stepped_address, stepped_address + 2); 645 flush_icache_range(stepped_address, stepped_address + 2);
654 } 646 }
655 stepped_opcode = 0; 647 stepped_opcode = 0;
656} 648}
@@ -736,7 +728,7 @@ static void write_mem_msg(int binary)
736 ebin_to_mem(ptr, (char*)addr, length); 728 ebin_to_mem(ptr, (char*)addr, length);
737 else 729 else
738 hex_to_mem(ptr, (char*)addr, length); 730 hex_to_mem(ptr, (char*)addr, length);
739 kgdb_flush_icache_range(addr, addr + length); 731 flush_icache_range(addr, addr + length);
740 ptr = 0; 732 ptr = 0;
741 send_ok_msg(); 733 send_ok_msg();
742 } 734 }
@@ -815,14 +807,10 @@ static void set_regs_msg(void)
815/* 807/*
816 * Bring up the ports.. 808 * Bring up the ports..
817 */ 809 */
818static int kgdb_serial_setup(void) 810static int __init kgdb_serial_setup(void)
819{ 811{
820 extern int kgdb_console_setup(struct console *co, char *options);
821 struct console dummy; 812 struct console dummy;
822 813 return kgdb_console_setup(&dummy, 0);
823 kgdb_console_setup(&dummy, 0);
824
825 return 0;
826} 814}
827#else 815#else
828#define kgdb_serial_setup() 0 816#define kgdb_serial_setup() 0
@@ -833,22 +821,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
833{ 821{
834 int sigval; 822 int sigval;
835 823
836 if (excep_code == NMI_VEC) {
837#ifndef CONFIG_KGDB_NMI
838 printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n");
839 return;
840#else /* CONFIG_KGDB_NMI */
841 if (!kgdb_enabled) {
842 kgdb_enabled = 1;
843 kgdb_init();
844 }
845#endif /* CONFIG_KGDB_NMI */
846 }
847
848 /* Ignore if we're disabled */
849 if (!kgdb_enabled)
850 return;
851
852 /* Enter GDB mode (e.g. after detach) */ 824 /* Enter GDB mode (e.g. after detach) */
853 if (!kgdb_in_gdb_mode) { 825 if (!kgdb_in_gdb_mode) {
854 /* Do serial setup, notify user, issue preemptive ack */ 826 /* Do serial setup, notify user, issue preemptive ack */
@@ -959,18 +931,10 @@ static void handle_exception(struct pt_regs *regs)
959 931
960 /* Get excode for command loop call, user access */ 932 /* Get excode for command loop call, user access */
961 asm("stc r2_bank, %0":"=r"(excep_code)); 933 asm("stc r2_bank, %0":"=r"(excep_code));
962 kgdb_excode = excep_code;
963
964 /* Other interesting environment items for reference */
965 asm("stc r6_bank, %0":"=r"(kgdb_g_imask));
966 kgdb_current = current;
967 kgdb_trapa_val = trapa_value;
968 934
969 /* Act on the exception */ 935 /* Act on the exception */
970 kgdb_command_loop(excep_code, trapa_value); 936 kgdb_command_loop(excep_code, trapa_value);
971 937
972 kgdb_current = NULL;
973
974 /* Copy back the (maybe modified) registers */ 938 /* Copy back the (maybe modified) registers */
975 for (count = 0; count < 16; count++) 939 for (count = 0; count < 16; count++)
976 regs->regs[count] = trap_registers.regs[count]; 940 regs->regs[count] = trap_registers.regs[count];
@@ -994,11 +958,8 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
994} 958}
995 959
996/* Initialise the KGDB data structures and serial configuration */ 960/* Initialise the KGDB data structures and serial configuration */
997int kgdb_init(void) 961int __init kgdb_init(void)
998{ 962{
999 if (!kgdb_enabled)
1000 return 1;
1001
1002 in_nmi = 0; 963 in_nmi = 0;
1003 kgdb_nofault = 0; 964 kgdb_nofault = 0;
1004 stepped_opcode = 0; 965 stepped_opcode = 0;
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 15ae322dbd74..b4469992d6b2 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -19,6 +19,7 @@
19#include <linux/tick.h> 19#include <linux/tick.h>
20#include <linux/reboot.h> 20#include <linux/reboot.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/preempt.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23#include <asm/mmu_context.h> 24#include <asm/mmu_context.h>
24#include <asm/pgalloc.h> 25#include <asm/pgalloc.h>
@@ -349,12 +350,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
349 unlazy_fpu(prev, task_pt_regs(prev)); 350 unlazy_fpu(prev, task_pt_regs(prev));
350#endif 351#endif
351 352
352#ifdef CONFIG_PREEMPT 353#if defined(CONFIG_GUSA) && defined(CONFIG_PREEMPT)
353 { 354 {
354 unsigned long flags;
355 struct pt_regs *regs; 355 struct pt_regs *regs;
356 356
357 local_irq_save(flags); 357 preempt_disable();
358 regs = task_pt_regs(prev); 358 regs = task_pt_regs(prev);
359 if (user_mode(regs) && regs->regs[15] >= 0xc0000000) { 359 if (user_mode(regs) && regs->regs[15] >= 0xc0000000) {
360 int offset = (int)regs->regs[15]; 360 int offset = (int)regs->regs[15];
@@ -365,7 +365,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
365 /* Go to rewind point */ 365 /* Go to rewind point */
366 regs->pc = regs->regs[0] + offset; 366 regs->pc = regs->regs[0] + offset;
367 } 367 }
368 local_irq_restore(flags); 368 preempt_enable_no_resched();
369 } 369 }
370#endif 370#endif
371 371
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 2cf7dec0d690..b3027a6775b9 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -22,6 +22,7 @@
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/kexec.h> 23#include <linux/kexec.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/smp.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/io.h> 27#include <asm/io.h>
27#include <asm/page.h> 28#include <asm/page.h>
@@ -42,7 +43,13 @@ extern void * __rd_start, * __rd_end;
42 * This value will be used at the very early stage of serial setup. 43 * This value will be used at the very early stage of serial setup.
43 * The bigger value means no problem. 44 * The bigger value means no problem.
44 */ 45 */
45struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; 46struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = {
47 [0] = {
48 .type = CPU_SH_NONE,
49 .loops_per_jiffy = 10000000,
50 },
51};
52EXPORT_SYMBOL(cpu_data);
46 53
47/* 54/*
48 * The machine vector. First entry in .machvec.init, or clobbered by 55 * The machine vector. First entry in .machvec.init, or clobbered by
@@ -272,6 +279,10 @@ void __init setup_arch(char **cmdline_p)
272 sh_mv.mv_setup(cmdline_p); 279 sh_mv.mv_setup(cmdline_p);
273 280
274 paging_init(); 281 paging_init();
282
283#ifdef CONFIG_SMP
284 plat_smp_setup();
285#endif
275} 286}
276 287
277static const char *cpu_name[] = { 288static const char *cpu_name[] = {
@@ -279,7 +290,7 @@ static const char *cpu_name[] = {
279 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", 290 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
280 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", 291 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
281 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", 292 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
282 [CPU_SH7712] = "SH7712", 293 [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720",
283 [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", 294 [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750",
284 [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", 295 [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R",
285 [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", 296 [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R",
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 37aef0a85197..548e4285b375 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -8,7 +8,7 @@
8#include <linux/vmalloc.h> 8#include <linux/vmalloc.h>
9#include <linux/pci.h> 9#include <linux/pci.h>
10#include <linux/irq.h> 10#include <linux/irq.h>
11 11#include <asm/sections.h>
12#include <asm/semaphore.h> 12#include <asm/semaphore.h>
13#include <asm/processor.h> 13#include <asm/processor.h>
14#include <asm/uaccess.h> 14#include <asm/uaccess.h>
@@ -43,7 +43,6 @@ EXPORT_SYMBOL(memcpy);
43EXPORT_SYMBOL(memset); 43EXPORT_SYMBOL(memset);
44EXPORT_SYMBOL(memmove); 44EXPORT_SYMBOL(memmove);
45EXPORT_SYMBOL(__copy_user); 45EXPORT_SYMBOL(__copy_user);
46EXPORT_SYMBOL(boot_cpu_data);
47 46
48#ifdef CONFIG_MMU 47#ifdef CONFIG_MMU
49EXPORT_SYMBOL(get_vm_area); 48EXPORT_SYMBOL(get_vm_area);
@@ -53,6 +52,7 @@ EXPORT_SYMBOL(get_vm_area);
53EXPORT_SYMBOL(__up); 52EXPORT_SYMBOL(__up);
54EXPORT_SYMBOL(__down); 53EXPORT_SYMBOL(__down);
55EXPORT_SYMBOL(__down_interruptible); 54EXPORT_SYMBOL(__down_interruptible);
55EXPORT_SYMBOL(__down_trylock);
56 56
57EXPORT_SYMBOL(__udelay); 57EXPORT_SYMBOL(__udelay);
58EXPORT_SYMBOL(__ndelay); 58EXPORT_SYMBOL(__ndelay);
@@ -128,7 +128,8 @@ DECLARE_EXPORT(__movstrSI12_i4);
128#endif /* __GNUC__ == 4 */ 128#endif /* __GNUC__ == 4 */
129#endif 129#endif
130 130
131#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) 131#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
132 defined(CONFIG_SH7705_CACHE_32KB))
132/* needed by some modules */ 133/* needed by some modules */
133EXPORT_SYMBOL(flush_cache_all); 134EXPORT_SYMBOL(flush_cache_all);
134EXPORT_SYMBOL(flush_cache_range); 135EXPORT_SYMBOL(flush_cache_range);
@@ -136,17 +137,11 @@ EXPORT_SYMBOL(flush_dcache_page);
136EXPORT_SYMBOL(__flush_purge_region); 137EXPORT_SYMBOL(__flush_purge_region);
137#endif 138#endif
138 139
139#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \ 140#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
140 defined(CONFIG_SH7705_CACHE_32KB)) 141 (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB))
141EXPORT_SYMBOL(clear_user_page); 142EXPORT_SYMBOL(clear_user_page);
142#endif 143#endif
143 144
144EXPORT_SYMBOL(__down_trylock);
145
146#ifdef CONFIG_SMP
147EXPORT_SYMBOL(synchronize_irq);
148#endif
149
150EXPORT_SYMBOL(csum_partial); 145EXPORT_SYMBOL(csum_partial);
151EXPORT_SYMBOL(csum_partial_copy_generic); 146EXPORT_SYMBOL(csum_partial_copy_generic);
152#ifdef CONFIG_IPV6 147#ifdef CONFIG_IPV6
@@ -154,3 +149,4 @@ EXPORT_SYMBOL(csum_ipv6_magic);
154#endif 149#endif
155EXPORT_SYMBOL(clear_page); 150EXPORT_SYMBOL(clear_page);
156EXPORT_SYMBOL(__clear_user); 151EXPORT_SYMBOL(__clear_user);
152EXPORT_SYMBOL(_ebss);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 706d81ccd101..2f42442cf164 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -507,13 +507,11 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
507 ctrl_inw(regs->pc - 4)); 507 ctrl_inw(regs->pc - 4));
508 break; 508 break;
509 } 509 }
510#ifdef CONFIG_GUSA
510 } else { 511 } else {
511 /* gUSA handling */ 512 /* gUSA handling */
512#ifdef CONFIG_PREEMPT 513 preempt_disable();
513 unsigned long flags;
514 514
515 local_irq_save(flags);
516#endif
517 if (regs->regs[15] >= 0xc0000000) { 515 if (regs->regs[15] >= 0xc0000000) {
518 int offset = (int)regs->regs[15]; 516 int offset = (int)regs->regs[15];
519 517
@@ -524,8 +522,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
524 regs->pc = regs->regs[0] + offset - 522 regs->pc = regs->regs[0] + offset -
525 instruction_size(ctrl_inw(regs->pc-4)); 523 instruction_size(ctrl_inw(regs->pc-4));
526 } 524 }
527#ifdef CONFIG_PREEMPT 525
528 local_irq_restore(flags); 526 preempt_enable_no_resched();
529#endif 527#endif
530 } 528 }
531 529
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 283e1425ced5..94075e1a1e61 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -3,68 +3,40 @@
3 * 3 *
4 * SMP support for the SuperH processors. 4 * SMP support for the SuperH processors.
5 * 5 *
6 * Copyright (C) 2002, 2003 Paul Mundt 6 * Copyright (C) 2002 - 2007 Paul Mundt
7 * Copyright (C) 2006 - 2007 Akio Idehara
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify it 9 * This file is subject to the terms and conditions of the GNU General Public
9 * under the terms of the GNU General Public License as published by the 10 * License. See the file "COPYING" in the main directory of this archive
10 * Free Software Foundation; either version 2 of the License, or (at your 11 * for more details.
11 * option) any later version.
12 */ 12 */
13
14#include <linux/err.h> 13#include <linux/err.h>
15#include <linux/cache.h> 14#include <linux/cache.h>
16#include <linux/cpumask.h> 15#include <linux/cpumask.h>
17#include <linux/delay.h> 16#include <linux/delay.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/spinlock.h> 18#include <linux/spinlock.h>
21#include <linux/threads.h> 19#include <linux/mm.h>
22#include <linux/module.h> 20#include <linux/module.h>
23#include <linux/time.h> 21#include <linux/interrupt.h>
24#include <linux/timex.h>
25#include <linux/sched.h>
26#include <linux/module.h>
27
28#include <asm/atomic.h> 22#include <asm/atomic.h>
29#include <asm/processor.h> 23#include <asm/processor.h>
30#include <asm/system.h> 24#include <asm/system.h>
31#include <asm/mmu_context.h> 25#include <asm/mmu_context.h>
32#include <asm/smp.h> 26#include <asm/smp.h>
27#include <asm/cacheflush.h>
28#include <asm/sections.h>
33 29
34/* 30int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
35 * This was written with the Sega Saturn (SMP SH-2 7604) in mind, 31int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
36 * but is designed to be usable regardless if there's an MMU
37 * present or not.
38 */
39struct sh_cpuinfo cpu_data[NR_CPUS];
40
41extern void per_cpu_trap_init(void);
42 32
43cpumask_t cpu_possible_map; 33cpumask_t cpu_possible_map;
44EXPORT_SYMBOL(cpu_possible_map); 34EXPORT_SYMBOL(cpu_possible_map);
45 35
46cpumask_t cpu_online_map; 36cpumask_t cpu_online_map;
47EXPORT_SYMBOL(cpu_online_map); 37EXPORT_SYMBOL(cpu_online_map);
48static atomic_t cpus_booted = ATOMIC_INIT(0);
49 38
50/* These are defined by the board-specific code. */ 39static atomic_t cpus_booted = ATOMIC_INIT(0);
51
52/*
53 * Cause the function described by call_data to be executed on the passed
54 * cpu. When the function has finished, increment the finished field of
55 * call_data.
56 */
57void __smp_send_ipi(unsigned int cpu, unsigned int action);
58
59/*
60 * Find the number of available processors
61 */
62unsigned int __smp_probe_cpus(void);
63
64/*
65 * Start a particular processor
66 */
67void __smp_slave_init(unsigned int cpu);
68 40
69/* 41/*
70 * Run specified function on a particular processor. 42 * Run specified function on a particular processor.
@@ -73,74 +45,123 @@ void __smp_call_function(unsigned int cpu);
73 45
74static inline void __init smp_store_cpu_info(unsigned int cpu) 46static inline void __init smp_store_cpu_info(unsigned int cpu)
75{ 47{
76 cpu_data[cpu].loops_per_jiffy = loops_per_jiffy; 48 struct sh_cpuinfo *c = cpu_data + cpu;
49
50 c->loops_per_jiffy = loops_per_jiffy;
77} 51}
78 52
79void __init smp_prepare_cpus(unsigned int max_cpus) 53void __init smp_prepare_cpus(unsigned int max_cpus)
80{ 54{
81 unsigned int cpu = smp_processor_id(); 55 unsigned int cpu = smp_processor_id();
82 int i;
83 56
84 atomic_set(&cpus_booted, 1); 57 init_new_context(current, &init_mm);
85 smp_store_cpu_info(cpu); 58 current_thread_info()->cpu = cpu;
86 59 plat_prepare_cpus(max_cpus);
87 for (i = 0; i < __smp_probe_cpus(); i++) 60
88 cpu_set(i, cpu_possible_map); 61#ifndef CONFIG_HOTPLUG_CPU
62 cpu_present_map = cpu_possible_map;
63#endif
89} 64}
90 65
91void __devinit smp_prepare_boot_cpu(void) 66void __devinit smp_prepare_boot_cpu(void)
92{ 67{
93 unsigned int cpu = smp_processor_id(); 68 unsigned int cpu = smp_processor_id();
94 69
70 __cpu_number_map[0] = cpu;
71 __cpu_logical_map[0] = cpu;
72
95 cpu_set(cpu, cpu_online_map); 73 cpu_set(cpu, cpu_online_map);
96 cpu_set(cpu, cpu_possible_map); 74 cpu_set(cpu, cpu_possible_map);
97} 75}
98 76
99int __cpu_up(unsigned int cpu) 77asmlinkage void __cpuinit start_secondary(void)
100{ 78{
101 struct task_struct *tsk; 79 unsigned int cpu;
80 struct mm_struct *mm = &init_mm;
102 81
103 tsk = fork_idle(cpu); 82 atomic_inc(&mm->mm_count);
83 atomic_inc(&mm->mm_users);
84 current->active_mm = mm;
85 BUG_ON(current->mm);
86 enter_lazy_tlb(mm, current);
104 87
105 if (IS_ERR(tsk)) 88 per_cpu_trap_init();
106 panic("Failed forking idle task for cpu %d\n", cpu); 89
107 90 preempt_disable();
108 task_thread_info(tsk)->cpu = cpu; 91
92 local_irq_enable();
93
94 calibrate_delay();
95
96 cpu = smp_processor_id();
97 smp_store_cpu_info(cpu);
109 98
110 cpu_set(cpu, cpu_online_map); 99 cpu_set(cpu, cpu_online_map);
111 100
112 return 0; 101 cpu_idle();
113} 102}
114 103
115int start_secondary(void *unused) 104extern struct {
105 unsigned long sp;
106 unsigned long bss_start;
107 unsigned long bss_end;
108 void *start_kernel_fn;
109 void *cpu_init_fn;
110 void *thread_info;
111} stack_start;
112
113int __cpuinit __cpu_up(unsigned int cpu)
116{ 114{
117 unsigned int cpu; 115 struct task_struct *tsk;
116 unsigned long timeout;
118 117
119 cpu = smp_processor_id(); 118 tsk = fork_idle(cpu);
119 if (IS_ERR(tsk)) {
120 printk(KERN_ERR "Failed forking idle task for cpu %d\n", cpu);
121 return PTR_ERR(tsk);
122 }
120 123
121 atomic_inc(&init_mm.mm_count); 124 /* Fill in data in head.S for secondary cpus */
122 current->active_mm = &init_mm; 125 stack_start.sp = tsk->thread.sp;
126 stack_start.thread_info = tsk->stack;
127 stack_start.bss_start = 0; /* don't clear bss for secondary cpus */
128 stack_start.start_kernel_fn = start_secondary;
123 129
124 smp_store_cpu_info(cpu); 130 flush_cache_all();
125 131
126 __smp_slave_init(cpu); 132 plat_start_cpu(cpu, (unsigned long)_stext);
127 preempt_disable();
128 per_cpu_trap_init();
129
130 atomic_inc(&cpus_booted);
131 133
132 cpu_idle(); 134 timeout = jiffies + HZ;
133 return 0; 135 while (time_before(jiffies, timeout)) {
136 if (cpu_online(cpu))
137 break;
138
139 udelay(10);
140 }
141
142 if (cpu_online(cpu))
143 return 0;
144
145 return -ENOENT;
134} 146}
135 147
136void __init smp_cpus_done(unsigned int max_cpus) 148void __init smp_cpus_done(unsigned int max_cpus)
137{ 149{
138 smp_mb(); 150 unsigned long bogosum = 0;
151 int cpu;
152
153 for_each_online_cpu(cpu)
154 bogosum += cpu_data[cpu].loops_per_jiffy;
155
156 printk(KERN_INFO "SMP: Total of %d processors activated "
157 "(%lu.%02lu BogoMIPS).\n", num_online_cpus(),
158 bogosum / (500000/HZ),
159 (bogosum / (5000/HZ)) % 100);
139} 160}
140 161
141void smp_send_reschedule(int cpu) 162void smp_send_reschedule(int cpu)
142{ 163{
143 __smp_send_ipi(cpu, SMP_MSG_RESCHEDULE); 164 plat_send_ipi(cpu, SMP_MSG_RESCHEDULE);
144} 165}
145 166
146static void stop_this_cpu(void *unused) 167static void stop_this_cpu(void *unused)
@@ -157,7 +178,6 @@ void smp_send_stop(void)
157 smp_call_function(stop_this_cpu, 0, 1, 0); 178 smp_call_function(stop_this_cpu, 0, 1, 0);
158} 179}
159 180
160
161struct smp_fn_call_struct smp_fn_call = { 181struct smp_fn_call_struct smp_fn_call = {
162 .lock = SPIN_LOCK_UNLOCKED, 182 .lock = SPIN_LOCK_UNLOCKED,
163 .finished = ATOMIC_INIT(0), 183 .finished = ATOMIC_INIT(0),
@@ -175,9 +195,6 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
175 unsigned int nr_cpus = atomic_read(&cpus_booted); 195 unsigned int nr_cpus = atomic_read(&cpus_booted);
176 int i; 196 int i;
177 197
178 if (nr_cpus < 2)
179 return 0;
180
181 /* Can deadlock when called with interrupts disabled */ 198 /* Can deadlock when called with interrupts disabled */
182 WARN_ON(irqs_disabled()); 199 WARN_ON(irqs_disabled());
183 200
@@ -189,7 +206,7 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
189 206
190 for (i = 0; i < nr_cpus; i++) 207 for (i = 0; i < nr_cpus; i++)
191 if (i != smp_processor_id()) 208 if (i != smp_processor_id())
192 __smp_call_function(i); 209 plat_send_ipi(i, SMP_MSG_FUNCTION);
193 210
194 if (wait) 211 if (wait)
195 while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1)); 212 while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1));
@@ -205,3 +222,143 @@ int setup_profiling_timer(unsigned int multiplier)
205 return 0; 222 return 0;
206} 223}
207 224
225static void flush_tlb_all_ipi(void *info)
226{
227 local_flush_tlb_all();
228}
229
230void flush_tlb_all(void)
231{
232 on_each_cpu(flush_tlb_all_ipi, 0, 1, 1);
233}
234
235static void flush_tlb_mm_ipi(void *mm)
236{
237 local_flush_tlb_mm((struct mm_struct *)mm);
238}
239
240/*
241 * The following tlb flush calls are invoked when old translations are
242 * being torn down, or pte attributes are changing. For single threaded
243 * address spaces, a new context is obtained on the current cpu, and tlb
244 * context on other cpus are invalidated to force a new context allocation
245 * at switch_mm time, should the mm ever be used on other cpus. For
246 * multithreaded address spaces, intercpu interrupts have to be sent.
247 * Another case where intercpu interrupts are required is when the target
248 * mm might be active on another cpu (eg debuggers doing the flushes on
249 * behalf of debugees, kswapd stealing pages from another process etc).
250 * Kanoj 07/00.
251 */
252
253void flush_tlb_mm(struct mm_struct *mm)
254{
255 preempt_disable();
256
257 if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
258 smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1);
259 } else {
260 int i;
261 for (i = 0; i < num_online_cpus(); i++)
262 if (smp_processor_id() != i)
263 cpu_context(i, mm) = 0;
264 }
265 local_flush_tlb_mm(mm);
266
267 preempt_enable();
268}
269
270struct flush_tlb_data {
271 struct vm_area_struct *vma;
272 unsigned long addr1;
273 unsigned long addr2;
274};
275
276static void flush_tlb_range_ipi(void *info)
277{
278 struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
279
280 local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2);
281}
282
283void flush_tlb_range(struct vm_area_struct *vma,
284 unsigned long start, unsigned long end)
285{
286 struct mm_struct *mm = vma->vm_mm;
287
288 preempt_disable();
289 if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
290 struct flush_tlb_data fd;
291
292 fd.vma = vma;
293 fd.addr1 = start;
294 fd.addr2 = end;
295 smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1);
296 } else {
297 int i;
298 for (i = 0; i < num_online_cpus(); i++)
299 if (smp_processor_id() != i)
300 cpu_context(i, mm) = 0;
301 }
302 local_flush_tlb_range(vma, start, end);
303 preempt_enable();
304}
305
306static void flush_tlb_kernel_range_ipi(void *info)
307{
308 struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
309
310 local_flush_tlb_kernel_range(fd->addr1, fd->addr2);
311}
312
313void flush_tlb_kernel_range(unsigned long start, unsigned long end)
314{
315 struct flush_tlb_data fd;
316
317 fd.addr1 = start;
318 fd.addr2 = end;
319 on_each_cpu(flush_tlb_kernel_range_ipi, (void *)&fd, 1, 1);
320}
321
322static void flush_tlb_page_ipi(void *info)
323{
324 struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
325
326 local_flush_tlb_page(fd->vma, fd->addr1);
327}
328
329void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
330{
331 preempt_disable();
332 if ((atomic_read(&vma->vm_mm->mm_users) != 1) ||
333 (current->mm != vma->vm_mm)) {
334 struct flush_tlb_data fd;
335
336 fd.vma = vma;
337 fd.addr1 = page;
338 smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1);
339 } else {
340 int i;
341 for (i = 0; i < num_online_cpus(); i++)
342 if (smp_processor_id() != i)
343 cpu_context(i, vma->vm_mm) = 0;
344 }
345 local_flush_tlb_page(vma, page);
346 preempt_enable();
347}
348
349static void flush_tlb_one_ipi(void *info)
350{
351 struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
352 local_flush_tlb_one(fd->addr1, fd->addr2);
353}
354
355void flush_tlb_one(unsigned long asid, unsigned long vaddr)
356{
357 struct flush_tlb_data fd;
358
359 fd.addr1 = asid;
360 fd.addr2 = vaddr;
361
362 smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1, 1);
363 local_flush_tlb_one(asid, vaddr);
364}
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S
index 91fb7024e06f..10bec45415ba 100644
--- a/arch/sh/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls.S
@@ -14,24 +14,6 @@
14#include <linux/sys.h> 14#include <linux/sys.h>
15#include <linux/linkage.h> 15#include <linux/linkage.h>
16 16
17#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
18#define sys_nfsservctl sys_ni_syscall
19#endif
20
21#if !defined(CONFIG_MMU)
22#define sys_madvise sys_ni_syscall
23#define sys_readahead sys_ni_syscall
24#define sys_mprotect sys_ni_syscall
25#define sys_msync sys_ni_syscall
26#define sys_mlock sys_ni_syscall
27#define sys_munlock sys_ni_syscall
28#define sys_mlockall sys_ni_syscall
29#define sys_munlockall sys_ni_syscall
30#define sys_mremap sys_ni_syscall
31#define sys_mincore sys_ni_syscall
32#define sys_remap_file_pages sys_ni_syscall
33#endif
34
35 .data 17 .data
36ENTRY(sys_call_table) 18ENTRY(sys_call_table)
37 .long sys_restart_syscall /* 0 - old "setup()" system call*/ 19 .long sys_restart_syscall /* 0 - old "setup()" system call*/
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index 8a545d54e2d3..628ec9a15e38 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -173,7 +173,8 @@ static int tmu_timer_init(void)
173 173
174 tmu_timer_stop(); 174 tmu_timer_stop();
175 175
176#if !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ 176#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
177 !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
177 !defined(CONFIG_CPU_SUBTYPE_SH7785) && \ 178 !defined(CONFIG_CPU_SUBTYPE_SH7785) && \
178 !defined(CONFIG_CPU_SUBTYPE_SHX3) 179 !defined(CONFIG_CPU_SUBTYPE_SHX3)
179 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); 180 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 67015044d74a..dcb46e71da1c 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -807,12 +807,13 @@ static inline void __init gdb_vbr_init(void)
807} 807}
808#endif 808#endif
809 809
810void __init per_cpu_trap_init(void) 810void __cpuinit per_cpu_trap_init(void)
811{ 811{
812 extern void *vbr_base; 812 extern void *vbr_base;
813 813
814#ifdef CONFIG_SH_STANDARD_BIOS 814#ifdef CONFIG_SH_STANDARD_BIOS
815 gdb_vbr_init(); 815 if (raw_smp_processor_id() == 0)
816 gdb_vbr_init();
816#endif 817#endif
817 818
818 /* NOTE: The VBR value should be at P1 819 /* NOTE: The VBR value should be at P1
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 9cb95af7b090..6d5abba2ee27 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -62,6 +62,8 @@ SECTIONS
62 __nosave_end = .; 62 __nosave_end = .;
63 63
64 PERCPU(PAGE_SIZE) 64 PERCPU(PAGE_SIZE)
65
66 . = ALIGN(L1_CACHE_BYTES);
65 .data.cacheline_aligned : { *(.data.cacheline_aligned) } 67 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
66 68
67 _edata = .; /* End of data section */ 69 _edata = .; /* End of data section */
@@ -89,7 +91,14 @@ SECTIONS
89 __con_initcall_end = .; 91 __con_initcall_end = .;
90 SECURITY_INIT 92 SECURITY_INIT
91 93
94 /* .exit.text is discarded at runtime, not link time, to deal with
95 references from .rodata */
96 .exit.text : { *(.exit.text) }
97 .exit.data : { *(.exit.data) }
98
92#ifdef CONFIG_BLK_DEV_INITRD 99#ifdef CONFIG_BLK_DEV_INITRD
100 . = ALIGN(PAGE_SIZE);
101
93 __initramfs_start = .; 102 __initramfs_start = .;
94 .init.ramfs : { *(.init.ramfs) } 103 .init.ramfs : { *(.init.ramfs) }
95 __initramfs_end = .; 104 __initramfs_end = .;
@@ -107,6 +116,7 @@ SECTIONS
107 *(.bss.page_aligned) 116 *(.bss.page_aligned)
108 *(.bss) 117 *(.bss)
109 . = ALIGN(4); 118 . = ALIGN(4);
119 _ebss = .; /* uClinux MTD sucks */
110 _end = . ; 120 _end = . ;
111 } 121 }
112 122