diff options
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/include/asm/leon.h | 12 | ||||
-rw-r--r-- | arch/sparc/include/asm/leon_amba.h | 6 | ||||
-rw-r--r-- | arch/sparc/kernel/leon_kernel.c | 14 |
3 files changed, 29 insertions, 3 deletions
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index 3ea5964c43b4..8580d1764f90 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h | |||
@@ -224,6 +224,18 @@ static inline void sparc_leon3_disable_cache(void) | |||
224 | "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2"); | 224 | "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2"); |
225 | }; | 225 | }; |
226 | 226 | ||
227 | static inline unsigned long sparc_leon3_asr17(void) | ||
228 | { | ||
229 | u32 asr17; | ||
230 | __asm__ __volatile__ ("rd %%asr17, %0\n\t" : "=r"(asr17)); | ||
231 | return asr17; | ||
232 | }; | ||
233 | |||
234 | static inline int sparc_leon3_cpuid(void) | ||
235 | { | ||
236 | return sparc_leon3_asr17() >> 28; | ||
237 | } | ||
238 | |||
227 | #endif /*!__ASSEMBLY__*/ | 239 | #endif /*!__ASSEMBLY__*/ |
228 | 240 | ||
229 | #ifdef CONFIG_SMP | 241 | #ifdef CONFIG_SMP |
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h index 618e88821795..263c719e96f5 100644 --- a/arch/sparc/include/asm/leon_amba.h +++ b/arch/sparc/include/asm/leon_amba.h | |||
@@ -100,9 +100,8 @@ struct leon3_irqctrl_regs_map { | |||
100 | u32 mpbroadcast; | 100 | u32 mpbroadcast; |
101 | u32 notused02; | 101 | u32 notused02; |
102 | u32 notused03; | 102 | u32 notused03; |
103 | u32 notused10; | 103 | u32 ampctrl; |
104 | u32 notused11; | 104 | u32 icsel[2]; |
105 | u32 notused12; | ||
106 | u32 notused13; | 105 | u32 notused13; |
107 | u32 notused20; | 106 | u32 notused20; |
108 | u32 notused21; | 107 | u32 notused21; |
@@ -112,6 +111,7 @@ struct leon3_irqctrl_regs_map { | |||
112 | u32 force[16]; | 111 | u32 force[16]; |
113 | /* Extended IRQ registers */ | 112 | /* Extended IRQ registers */ |
114 | u32 intid[16]; /* 0xc0 */ | 113 | u32 intid[16]; /* 0xc0 */ |
114 | u32 unused[(0x1000-0x100)/4]; | ||
115 | }; | 115 | }; |
116 | 116 | ||
117 | struct leon3_apbuart_regs_map { | 117 | struct leon3_apbuart_regs_map { |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 80ba8f517318..91a978f4d83b 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -108,6 +108,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
108 | struct device_node *rootnp, *np; | 108 | struct device_node *rootnp, *np; |
109 | struct property *pp; | 109 | struct property *pp; |
110 | int len; | 110 | int len; |
111 | int cpu, icsel; | ||
111 | 112 | ||
112 | leondebug_irq_disable = 0; | 113 | leondebug_irq_disable = 0; |
113 | leon_debug_irqout = 0; | 114 | leon_debug_irqout = 0; |
@@ -160,6 +161,19 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
160 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); | 161 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); |
161 | # endif | 162 | # endif |
162 | 163 | ||
164 | /* | ||
165 | * The IRQ controller may (if implemented) consist of multiple | ||
166 | * IRQ controllers, each mapped on a 4Kb boundary. | ||
167 | * Each CPU may be routed to different IRQCTRLs, however | ||
168 | * we assume that all CPUs (in SMP system) is routed to the | ||
169 | * same IRQ Controller, and for non-SMP only one IRQCTRL is | ||
170 | * accessed anyway. | ||
171 | * In AMP systems, Linux must run on CPU0 for the time being. | ||
172 | */ | ||
173 | cpu = sparc_leon3_cpuid(); | ||
174 | icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]); | ||
175 | icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf; | ||
176 | leon3_irqctrl_regs += icsel; | ||
163 | } else { | 177 | } else { |
164 | goto bad; | 178 | goto bad; |
165 | } | 179 | } |