diff options
Diffstat (limited to 'arch/sh/kernel')
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 | */ |
216 | asmlinkage void __init sh_cpu_init(void) | 220 | |
221 | asmlinkage 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 | # |
4 | obj-y += imask.o | 4 | obj-y += imask.o intc.o |
5 | 5 | ||
6 | obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o | 6 | obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o |
7 | obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o | 7 | obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o |
8 | obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o | ||
9 | obj-$(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 | |||
36 | struct intc_handle_int { | ||
37 | unsigned int irq; | ||
38 | unsigned long handle; | ||
39 | }; | ||
40 | |||
41 | struct 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) \ | 64 | static unsigned int intc_prio_level[NR_IRQS]; /* for now */ |
32 | (desc->member + _INTC_IDX(data)) | ||
33 | 65 | ||
34 | static inline struct intc_desc *get_intc_desc(unsigned int irq) | 66 | static 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 | ||
40 | static inline unsigned int set_field(unsigned int value, | 72 | static 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 | ||
50 | static inline unsigned int set_prio_field(struct intc_desc *desc, | 84 | static 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 | ||
60 | static void disable_prio_16(struct intc_desc *desc, unsigned int data) | 89 | static 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 | ||
67 | static void enable_prio_16(struct intc_desc *desc, unsigned int data) | 94 | static 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 | ||
75 | static void disable_prio_32(struct intc_desc *desc, unsigned int data) | 99 | static 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 | ||
82 | static void enable_prio_32(struct intc_desc *desc, unsigned int data) | 104 | static 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 | ||
90 | static void disable_mask_8(struct intc_desc *desc, unsigned int data) | 109 | static 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 | ||
96 | static void enable_mask_8(struct intc_desc *desc, unsigned int data) | 114 | enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; |
115 | |||
116 | static 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 | |||
127 | enum { 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 | |||
134 | static 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 | ||
102 | static void disable_mask_32(struct intc_desc *desc, unsigned int data) | 144 | static 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 | ||
108 | static void enable_mask_32(struct intc_desc *desc, unsigned int data) | 154 | static 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 | ||
114 | enum { REG_FN_ERROR=0, | 164 | static 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, | |
118 | static 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 | ||
128 | static void intc_enable(unsigned int irq) | 177 | static 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 | |||
190 | static 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); | 203 | static void intc_enable(unsigned int irq) |
204 | { | ||
205 | _intc_enable(irq, (unsigned long)get_irq_chip_data(irq)); | ||
134 | } | 206 | } |
135 | 207 | ||
136 | static void intc_disable(unsigned int irq) | 208 | static 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 | ||
144 | static void set_sense_16(struct intc_desc *desc, unsigned int data) | 222 | static 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 | ||
154 | static void set_sense_32(struct intc_desc *desc, unsigned int data) | 250 | int 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 | ||
173 | static int intc_set_sense(unsigned int irq, unsigned int type) | 286 | static 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 | ||
221 | static unsigned int __init intc_find_mask_handler(unsigned int width) | 304 | static 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 | |||
234 | static 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 | ||
247 | static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) | 318 | static 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 | ||
291 | static unsigned int __init intc_mask_data(struct intc_desc *desc, | 363 | static 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 | ||
318 | static unsigned int __init intc_prio_data(struct intc_desc *desc, | 411 | static 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 | ||
350 | static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, | 458 | static 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 | |||
486 | static 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 | ||
558 | static 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 | |||
391 | void __init register_intc_controller(struct intc_desc *desc) | 575 | void __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 | |||
18 | static 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 | |||
24 | static 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 | |||
33 | static 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 | */ | ||
54 | void 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 | ||
17 | int __init detect_cpu_and_cache_system(void) | 16 | int __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 | ||
15 | enum { | ||
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 | |||
32 | static 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 | |||
51 | static 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 | |||
57 | static 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 | |||
67 | static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups, | ||
68 | NULL, NULL, prio_registers, NULL); | ||
69 | |||
15 | static struct plat_sci_port sci_platform_data[] = { | 70 | static 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 | ||
55 | static 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 | |||
71 | static unsigned long ipr_offsets[] = { | ||
72 | 0xf8080000, /* IPRC */ | ||
73 | 0xf8080002, /* IPRD */ | ||
74 | 0xf8080004, /* IPRE */ | ||
75 | 0xf8080006, /* IPRF */ | ||
76 | 0xf8080008, /* IPRG */ | ||
77 | }; | ||
78 | |||
79 | static 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 | |||
91 | void __init plat_irq_setup(void) | 110 | void __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 @@ | |||
17 | int __init detect_cpu_and_cache_system(void) | 17 | int __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 | ||
15 | enum { | ||
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 | |||
52 | static 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 | |||
111 | static 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 | |||
144 | static 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 | |||
163 | static 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 | |||
169 | static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, | ||
170 | NULL, mask_registers, prio_registers, NULL); | ||
171 | |||
15 | static struct plat_sci_port sci_platform_data[] = { | 172 | static 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 | ||
60 | static 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 | |||
81 | static 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 | |||
98 | static 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 | |||
110 | void __init plat_irq_setup(void) | 217 | void __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 |
8 | obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o | 8 | obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o |
9 | obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh7709.o | 9 | obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o |
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh7709.o | 10 | obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o |
11 | obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o | 11 | obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o |
12 | obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o | 12 | obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o |
13 | obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o | 13 | obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o |
14 | obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o | 14 | obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o |
15 | obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o | ||
15 | 16 | ||
16 | # Primary on-chip clocks (common) | 17 | # Primary on-chip clocks (common) |
17 | clock-$(CONFIG_CPU_SH3) := clock-sh3.o | 18 | clock-$(CONFIG_CPU_SH3) := clock-sh3.o |
@@ -19,5 +20,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o | |||
19 | clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o | 20 | clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o |
20 | clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o | 21 | clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o |
21 | clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o | 22 | clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o |
23 | clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o | ||
22 | 24 | ||
23 | obj-y += $(clock-y) | 25 | obj-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 | |||
18 | enum { | ||
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 | |||
39 | static 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 | |||
60 | static 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 | |||
69 | static struct intc_prio priorities[] __initdata = { | ||
70 | INTC_PRIO(DMAC, 7), | ||
71 | INTC_PRIO(SCIF2, 3), | ||
72 | INTC_PRIO(SCIF0, 3), | ||
73 | }; | ||
74 | |||
75 | static 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 | |||
87 | static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups, | ||
88 | priorities, NULL, prio_registers, NULL); | ||
89 | |||
90 | static 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 | |||
95 | static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL, | ||
96 | priorities, NULL, prio_registers, NULL); | ||
15 | 97 | ||
16 | static struct plat_sci_port sci_platform_data[] = { | 98 | static 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 | ||
122 | static 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 | |||
142 | static struct sh_rtc_platform_info rtc_info = { | ||
143 | .capabilities = RTC_CAP_4_DIGIT_YEAR, | ||
144 | }; | ||
145 | |||
146 | static 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 | |||
40 | static struct platform_device *sh7705_devices[] __initdata = { | 156 | static struct platform_device *sh7705_devices[] __initdata = { |
41 | &sci_device, | 157 | &sci_device, |
158 | &rtc_device, | ||
42 | }; | 159 | }; |
43 | 160 | ||
44 | static int __init sh7705_devices_setup(void) | 161 | static 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 | ||
51 | static struct ipr_data ipr_irq_table[] = { | 168 | void __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 | |||
72 | static 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 | |||
83 | static 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 | ||
95 | void __init plat_irq_setup(void) | 177 | void __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 | |||
15 | static 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 | |||
26 | static struct platform_device sci_device = { | ||
27 | .name = "sh-sci", | ||
28 | .id = -1, | ||
29 | .dev = { | ||
30 | .platform_data = sci_platform_data, | ||
31 | }, | ||
32 | }; | ||
33 | |||
34 | static struct platform_device *sh7708_devices[] __initdata = { | ||
35 | &sci_device, | ||
36 | }; | ||
37 | |||
38 | static 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 | |||
15 | static 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 | |||
35 | static 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 | |||
56 | static struct platform_device sci_device = { | ||
57 | .name = "sh-sci", | ||
58 | .id = -1, | ||
59 | .dev = { | ||
60 | .platform_data = sci_platform_data, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static 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 | |||
71 | static struct platform_device *sh7709_devices[] __initdata = { | ||
72 | &sci_device, | ||
73 | &rtc_device, | ||
74 | }; | ||
75 | |||
76 | static 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 | |||
83 | static 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 | |||
122 | static 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 | |||
130 | static 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 | |||
142 | void __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 | |||
21 | enum { | ||
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 | |||
42 | static 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 | |||
74 | static 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 | |||
84 | static 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 | |||
91 | static 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 | |||
111 | static 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) | ||
117 | static 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 | |||
122 | static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL, | ||
123 | priorities, NULL, prio_registers, NULL); | ||
124 | #endif | ||
125 | |||
126 | static 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 | |||
146 | static 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 | |||
153 | static 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 | |||
184 | static struct platform_device sci_device = { | ||
185 | .name = "sh-sci", | ||
186 | .id = -1, | ||
187 | .dev = { | ||
188 | .platform_data = sci_platform_data, | ||
189 | }, | ||
190 | }; | ||
191 | |||
192 | static struct platform_device *sh770x_devices[] __initdata = { | ||
193 | &sci_device, | ||
194 | &rtc_device, | ||
195 | }; | ||
196 | |||
197 | static 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 | |||
207 | void __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 | |||
221 | void __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 | |||
18 | enum { | ||
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 | |||
40 | static 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 | |||
66 | static 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 | |||
76 | static 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 | |||
88 | static 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 | |||
103 | static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, | ||
104 | priorities, NULL, prio_registers, NULL); | ||
105 | |||
106 | static 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 | |||
111 | static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL, | ||
112 | priorities, NULL, prio_registers, NULL); | ||
113 | |||
114 | static 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 | |||
134 | static struct sh_rtc_platform_info rtc_info = { | ||
135 | .capabilities = RTC_CAP_4_DIGIT_YEAR, | ||
136 | }; | ||
137 | |||
138 | static 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 | ||
16 | static struct plat_sci_port sci_platform_data[] = { | 148 | static 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 | ||
41 | static struct platform_device *sh7710_devices[] __initdata = { | 173 | static struct platform_device *sh7710_devices[] __initdata = { |
42 | &sci_device, | 174 | &sci_device, |
175 | &rtc_device, | ||
43 | }; | 176 | }; |
44 | 177 | ||
45 | static int __init sh7710_devices_setup(void) | 178 | static 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 | ||
52 | static struct ipr_data ipr_irq_table[] = { | 185 | void __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 | |||
80 | static 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 | |||
92 | static 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 | ||
104 | void __init plat_irq_setup(void) | 194 | void __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 | |||
26 | static 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 | |||
49 | static struct sh_rtc_platform_info rtc_info = { | ||
50 | .capabilities = RTC_CAP_4_DIGIT_YEAR, | ||
51 | }; | ||
52 | |||
53 | static 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 | |||
63 | static 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 | |||
80 | static struct platform_device sci_device = { | ||
81 | .name = "sh-sci", | ||
82 | .id = -1, | ||
83 | .dev = { | ||
84 | .platform_data = sci_platform_data, | ||
85 | }, | ||
86 | }; | ||
87 | |||
88 | static struct platform_device *sh7720_devices[] __initdata = { | ||
89 | &rtc_device, | ||
90 | &sci_device, | ||
91 | }; | ||
92 | |||
93 | static 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 | |||
100 | enum { | ||
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 | |||
119 | static 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 | |||
145 | static 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 | |||
156 | static 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 | |||
166 | static 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 | |||
179 | static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups, | ||
180 | priorities, NULL, prio_registers, NULL); | ||
181 | |||
182 | static struct intc_sense_reg sense_registers[] __initdata = { | ||
183 | { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, | ||
184 | }; | ||
185 | |||
186 | static 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 | |||
192 | static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq, | ||
193 | NULL, priorities, NULL, prio_registers, sense_registers); | ||
194 | |||
195 | void __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 | |||
207 | void __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 | ||
107 | static struct intc_vect vectors[] = { | 107 | static 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 | ||
121 | static struct intc_group groups[] = { | 121 | static 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 | ||
129 | static struct intc_prio priorities[] = { | 129 | static 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 | ||
135 | static struct intc_prio_reg prio_registers[] = { | 135 | static 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 | ||
145 | static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, | 145 | static 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) |
153 | static struct intc_vect vectors_dma4[] = { | 153 | static 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 | ||
159 | static struct intc_group groups_dma4[] = { | 159 | static 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) |
171 | static struct intc_vect vectors_dma8[] = { | 171 | static 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 | ||
179 | static struct intc_group groups_dma8[] = { | 179 | static 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) |
194 | static struct intc_vect vectors_tmu34[] = { | 194 | static 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 | ||
198 | static struct intc_mask_reg mask_registers[] = { | 198 | static 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 */ |
213 | static struct intc_vect vectors_irlm[] = { | 213 | static 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) |
223 | static struct intc_vect vectors_pci[] = { | 223 | static 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 | ||
230 | static struct intc_group groups_pci[] = { | 230 | static 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 */ | 285 | void __init plat_irq_setup_pins(int mode) |
286 | void __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 | ||
15 | enum { | ||
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 | |||
46 | static 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 | |||
81 | static 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 | |||
95 | static 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 | |||
104 | static 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 | |||
120 | static 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 | |||
134 | static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups, | ||
135 | priorities, mask_registers, prio_registers, NULL); | ||
136 | |||
137 | static 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 | |||
142 | static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, | ||
143 | priorities, mask_registers, prio_registers, NULL); | ||
144 | |||
15 | static struct plat_sci_port sci_platform_data[] = { | 145 | static 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 | ||
55 | static struct intc2_data intc2_irq_table[] = { | 190 | void __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 | |||
99 | static 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 | |||
112 | static 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 | |||
142 | static unsigned long ipr_offsets[] = { | ||
143 | 0xffd00004UL, /* 0: IPRA */ | ||
144 | 0xffd00008UL, /* 1: IPRB */ | ||
145 | 0xffd0000cUL, /* 2: IPRC */ | ||
146 | 0xffd00010UL, /* 3: IPRD */ | ||
147 | }; | ||
148 | |||
149 | static 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 | ||
161 | void __init plat_irq_setup(void) | 201 | void __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 | */ |
59 | void sq_flush_range(unsigned long start, unsigned int len) | 59 | void 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 | |||
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o | 10 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o |
11 | obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o | 11 | obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o |
12 | 12 | ||
13 | # SMP setup | ||
14 | smp-$(CONFIG_CPU_SUBTYPE_SHX3) := smp-shx3.o | ||
15 | |||
13 | # Primary on-chip clocks (common) | 16 | # Primary on-chip clocks (common) |
14 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o | 17 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o |
15 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o | 18 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o |
@@ -18,4 +21,5 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o | |||
18 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o | 21 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o |
19 | clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o | 22 | clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o |
20 | 23 | ||
21 | obj-y += $(clock-y) | 24 | obj-y += $(clock-y) |
25 | obj-$(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 | |||
45 | void __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 | ||
87 | static struct intc_vect vectors[] = { | 87 | static 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 | ||
120 | static struct intc_group groups[] = { | 120 | static 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 | ||
133 | static struct intc_prio priorities[] = { | 133 | static 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 | ||
141 | static struct intc_mask_reg mask_registers[] = { | 141 | static 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 | ||
171 | static struct intc_prio_reg prio_registers[] = { | 171 | static 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 | ||
188 | static struct intc_sense_reg sense_registers[] = { | 188 | static 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 | |||
55 | void __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 | ||
15 | static struct resource rtc_resources[] = { | 16 | static 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 | ||
117 | static struct intc_vect vectors[] = { | 118 | static 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 | ||
153 | static struct intc_group groups[] = { | 154 | static 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 | ||
170 | static struct intc_prio priorities[] = { | 171 | static 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 | ||
175 | static struct intc_mask_reg mask_registers[] = { | 176 | static 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 | ||
183 | static struct intc_prio_reg prio_registers[] = { | 184 | static 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 | ||
195 | static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, | 198 | static 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 | ||
200 | static struct intc_vect irq_vectors[] = { | 203 | static 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 | ||
207 | static struct intc_mask_reg irq_mask_registers[] = { | 210 | static 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 | ||
212 | static struct intc_prio_reg irq_prio_registers[] = { | 215 | static 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 | ||
217 | static struct intc_sense_reg irq_sense_registers[] = { | 220 | static 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 | ||
228 | static struct intc_vect irl_vectors[] = { | 231 | static 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 | ||
239 | static struct intc_mask_reg irl3210_mask_registers[] = { | 242 | static 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 | ||
247 | static struct intc_mask_reg irl7654_mask_registers[] = { | 250 | static 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, | |||
259 | static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, | 262 | static 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 | |||
262 | void __init plat_irq_setup(void) | 272 | void __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 | ||
15 | static struct plat_sci_port sci_platform_data[] = { | 18 | static 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 | ||
75 | static struct intc2_data intc2_irq_table[] = { | 78 | enum { |
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 | ||
100 | static struct intc2_desc intc2_irq_desc __read_mostly = { | 123 | static 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, | 164 | static 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 = { | 181 | static 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 | |||
190 | static 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 | |||
211 | static 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 | ||
230 | static 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 | |||
235 | static 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 | |||
240 | static 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 | |||
245 | static struct intc_sense_reg sense_registers[] __initdata = { | ||
246 | { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, | ||
247 | IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
248 | }; | ||
249 | |||
250 | static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123, | ||
251 | NULL, NULL, mask_registers, prio_registers, | ||
252 | sense_registers); | ||
253 | |||
254 | static 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 | |||
260 | static 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 | |||
271 | static 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 | |||
282 | static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123, | ||
283 | NULL, NULL, mask_registers, NULL, NULL); | ||
284 | |||
285 | static 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 | |||
113 | void __init plat_irq_setup(void) | 295 | void __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 | |||
313 | void __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 | ||
351 | void __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 | ||
16 | static struct plat_sci_port sci_platform_data[] = { | 17 | static 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 | ||
61 | static struct intc2_data intc2_irq_table[] = { | 62 | enum { |
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 | |||
100 | static 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 | ||
69 | static struct intc2_desc intc2_irq_desc __read_mostly = { | 148 | static 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, | 168 | static 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 = { | 175 | static 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 | |||
200 | static 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 | |||
221 | static 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 */ | ||
225 | static 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 | |||
230 | static struct intc_sense_reg sense_registers[] __initdata = { | ||
231 | { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, | ||
80 | }; | 232 | }; |
81 | 233 | ||
234 | static 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 */ | ||
239 | static 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 | |||
250 | static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups, | ||
251 | priorities, mask_registers, prio_registers, NULL); | ||
252 | |||
253 | void __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 | |||
82 | void __init plat_irq_setup(void) | 267 | void __init plat_irq_setup(void) |
83 | { | 268 | { |
84 | register_intc2_controller(&intc2_irq_desc); | 269 | register_intc_controller(&intc_desc); |
270 | } | ||
271 | |||
272 | void __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 | |||
17 | void __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 | |||
41 | void __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 | |||
54 | void 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 | |||
68 | int plat_smp_processor_id(void) | ||
69 | { | ||
70 | return ctrl_inl(0xff000048); /* CPIDR */ | ||
71 | } | ||
72 | |||
73 | void 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 | |||
83 | struct ipi_data { | ||
84 | void (*handler)(void *); | ||
85 | void *arg; | ||
86 | unsigned int message; | ||
87 | }; | ||
88 | |||
89 | static 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 | |||
105 | static struct ipi_data ipi_handlers[SMP_MSG_NR]; | ||
106 | |||
107 | int 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 | ||
78 | static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) | 78 | static 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 | ||
144 | static int __init sh_cpufreq_module_init(void) | 142 | static 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 | |||
65 | static struct uart_port scif_port = { | 76 | static 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 | ||
70 | static void scif_sercon_putc(int c) | 81 | static 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) | ||
121 | static 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 | ||
166 | static int __initdata keep_early; | 193 | static int __init setup_early_printk(char *buf) |
167 | static int early_console_initialized; | ||
168 | |||
169 | int __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 |
178 | work_resched: | 178 | work_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 | ||
95 | 10: | ||
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 |
108 | 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF | 112 | 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF |
109 | #endif | 113 | #endif |
114 | ENTRY(stack_start) | ||
110 | 2: .long init_thread_union+THREAD_SIZE | 115 | 2: .long init_thread_union+THREAD_SIZE |
111 | 3: .long __bss_start | 116 | 3: .long __bss_start |
112 | 4: .long _end | 117 | 4: .long _end |
113 | 5: .long start_kernel | 118 | 5: .long start_kernel |
114 | 6: .long sh_cpu_init | 119 | 6: .long sh_cpu_init |
120 | 7: .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; | |||
150 | char kgdb_in_gdb_mode; | 150 | char kgdb_in_gdb_mode; |
151 | char in_nmi; /* Set during NMI to prevent reentry */ | 151 | char in_nmi; /* Set during NMI to prevent reentry */ |
152 | int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ | 152 | int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ |
153 | int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ | ||
154 | |||
155 | /* Exposed for user access */ | ||
156 | struct task_struct *kgdb_current; | ||
157 | unsigned int kgdb_g_imask; | ||
158 | int kgdb_trapa_val; | ||
159 | int 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 | */ |
818 | static int kgdb_serial_setup(void) | 810 | static 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 */ |
997 | int kgdb_init(void) | 961 | int __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 | */ |
45 | struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; | 46 | struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = { |
47 | [0] = { | ||
48 | .type = CPU_SH_NONE, | ||
49 | .loops_per_jiffy = 10000000, | ||
50 | }, | ||
51 | }; | ||
52 | EXPORT_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 | ||
277 | static const char *cpu_name[] = { | 288 | static 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); | |||
43 | EXPORT_SYMBOL(memset); | 43 | EXPORT_SYMBOL(memset); |
44 | EXPORT_SYMBOL(memmove); | 44 | EXPORT_SYMBOL(memmove); |
45 | EXPORT_SYMBOL(__copy_user); | 45 | EXPORT_SYMBOL(__copy_user); |
46 | EXPORT_SYMBOL(boot_cpu_data); | ||
47 | 46 | ||
48 | #ifdef CONFIG_MMU | 47 | #ifdef CONFIG_MMU |
49 | EXPORT_SYMBOL(get_vm_area); | 48 | EXPORT_SYMBOL(get_vm_area); |
@@ -53,6 +52,7 @@ EXPORT_SYMBOL(get_vm_area); | |||
53 | EXPORT_SYMBOL(__up); | 52 | EXPORT_SYMBOL(__up); |
54 | EXPORT_SYMBOL(__down); | 53 | EXPORT_SYMBOL(__down); |
55 | EXPORT_SYMBOL(__down_interruptible); | 54 | EXPORT_SYMBOL(__down_interruptible); |
55 | EXPORT_SYMBOL(__down_trylock); | ||
56 | 56 | ||
57 | EXPORT_SYMBOL(__udelay); | 57 | EXPORT_SYMBOL(__udelay); |
58 | EXPORT_SYMBOL(__ndelay); | 58 | EXPORT_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 */ |
133 | EXPORT_SYMBOL(flush_cache_all); | 134 | EXPORT_SYMBOL(flush_cache_all); |
134 | EXPORT_SYMBOL(flush_cache_range); | 135 | EXPORT_SYMBOL(flush_cache_range); |
@@ -136,17 +137,11 @@ EXPORT_SYMBOL(flush_dcache_page); | |||
136 | EXPORT_SYMBOL(__flush_purge_region); | 137 | EXPORT_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)) |
141 | EXPORT_SYMBOL(clear_user_page); | 142 | EXPORT_SYMBOL(clear_user_page); |
142 | #endif | 143 | #endif |
143 | 144 | ||
144 | EXPORT_SYMBOL(__down_trylock); | ||
145 | |||
146 | #ifdef CONFIG_SMP | ||
147 | EXPORT_SYMBOL(synchronize_irq); | ||
148 | #endif | ||
149 | |||
150 | EXPORT_SYMBOL(csum_partial); | 145 | EXPORT_SYMBOL(csum_partial); |
151 | EXPORT_SYMBOL(csum_partial_copy_generic); | 146 | EXPORT_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 |
155 | EXPORT_SYMBOL(clear_page); | 150 | EXPORT_SYMBOL(clear_page); |
156 | EXPORT_SYMBOL(__clear_user); | 151 | EXPORT_SYMBOL(__clear_user); |
152 | EXPORT_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 | /* | 30 | int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ |
35 | * This was written with the Sega Saturn (SMP SH-2 7604) in mind, | 31 | int __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 | */ | ||
39 | struct sh_cpuinfo cpu_data[NR_CPUS]; | ||
40 | |||
41 | extern void per_cpu_trap_init(void); | ||
42 | 32 | ||
43 | cpumask_t cpu_possible_map; | 33 | cpumask_t cpu_possible_map; |
44 | EXPORT_SYMBOL(cpu_possible_map); | 34 | EXPORT_SYMBOL(cpu_possible_map); |
45 | 35 | ||
46 | cpumask_t cpu_online_map; | 36 | cpumask_t cpu_online_map; |
47 | EXPORT_SYMBOL(cpu_online_map); | 37 | EXPORT_SYMBOL(cpu_online_map); |
48 | static atomic_t cpus_booted = ATOMIC_INIT(0); | ||
49 | 38 | ||
50 | /* These are defined by the board-specific code. */ | 39 | static 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 | */ | ||
57 | void __smp_send_ipi(unsigned int cpu, unsigned int action); | ||
58 | |||
59 | /* | ||
60 | * Find the number of available processors | ||
61 | */ | ||
62 | unsigned int __smp_probe_cpus(void); | ||
63 | |||
64 | /* | ||
65 | * Start a particular processor | ||
66 | */ | ||
67 | void __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 | ||
74 | static inline void __init smp_store_cpu_info(unsigned int cpu) | 46 | static 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 | ||
79 | void __init smp_prepare_cpus(unsigned int max_cpus) | 53 | void __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 | ||
91 | void __devinit smp_prepare_boot_cpu(void) | 66 | void __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 | ||
99 | int __cpu_up(unsigned int cpu) | 77 | asmlinkage 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 | ||
115 | int start_secondary(void *unused) | 104 | extern 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 | |||
113 | int __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 | ||
136 | void __init smp_cpus_done(unsigned int max_cpus) | 148 | void __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 | ||
141 | void smp_send_reschedule(int cpu) | 162 | void 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 | ||
146 | static void stop_this_cpu(void *unused) | 167 | static 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 | |||
161 | struct smp_fn_call_struct smp_fn_call = { | 181 | struct 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 | ||
225 | static void flush_tlb_all_ipi(void *info) | ||
226 | { | ||
227 | local_flush_tlb_all(); | ||
228 | } | ||
229 | |||
230 | void flush_tlb_all(void) | ||
231 | { | ||
232 | on_each_cpu(flush_tlb_all_ipi, 0, 1, 1); | ||
233 | } | ||
234 | |||
235 | static 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 | |||
253 | void 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 | |||
270 | struct flush_tlb_data { | ||
271 | struct vm_area_struct *vma; | ||
272 | unsigned long addr1; | ||
273 | unsigned long addr2; | ||
274 | }; | ||
275 | |||
276 | static 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 | |||
283 | void 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 | |||
306 | static 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 | |||
313 | void 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 | |||
322 | static 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 | |||
329 | void 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 | |||
349 | static 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 | |||
355 | void 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 |
36 | ENTRY(sys_call_table) | 18 | ENTRY(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 | ||
810 | void __init per_cpu_trap_init(void) | 810 | void __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 | ||