From 25a68b8cd8ea1553f8b56278418d6c1ecc12e247 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Wed, 22 Sep 2010 10:19:34 +0200 Subject: [PATCH] SPARC/LEON: added support for AMP systems with IRQAMP IRQ Controller. Signed-off-by: Daniel Hellstrom --- arch/sparc/include/asm/leon.h | 12 ++++++++++++ arch/sparc/include/asm/leon_amba.h | 6 +++--- arch/sparc/kernel/leon_kernel.c | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h @@ -224,6 +224,18 @@ static inline void sparc_leon3_disable_c "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2"); }; +static inline unsigned long sparc_leon3_asr17(void) +{ + u32 asr17; + __asm__ __volatile__ ("rd %%asr17, %0\n\t" : "=r"(asr17)); + return asr17; +}; + +static inline int sparc_leon3_cpuid(void) +{ + return sparc_leon3_asr17() >> 28; +} + #endif /*!__ASSEMBLY__*/ #ifdef CONFIG_SMP --- 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 { u32 mpbroadcast; u32 notused02; u32 notused03; - u32 notused10; - u32 notused11; - u32 notused12; + u32 ampctrl; + u32 icsel[2]; u32 notused13; u32 notused20; u32 notused21; @@ -112,6 +111,7 @@ struct leon3_irqctrl_regs_map { u32 force[16]; /* Extended IRQ registers */ u32 intid[16]; /* 0xc0 */ + u32 unused[(0x1000-0x100)/4]; }; struct leon3_apbuart_regs_map { --- 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 struct device_node *rootnp, *np; struct property *pp; int len; + int cpu, icsel; leondebug_irq_disable = 0; leon_debug_irqout = 0; @@ -153,6 +154,19 @@ void __init leon_init_timers(irq_handler LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); # endif + /* The IRQ controller may (if implemented) consist of multiple + * IRQ controllers, each mapped on a 4Kb boundary. + * Each CPU may be routed to different IRQCTRLs, however + * we assume that all CPUs (in SMP system) is routed to the + * same IRQ Controller, and for non-SMP only one IRQCTRL is + * accessed anyway. + * In AMP systems, Linux may not be run on CPU0. + */ + cpu = sparc_leon3_cpuid(); + icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]); + icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf; + leon3_irqctrl_regs += icsel; + LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0); eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus) >> 16) & 0xf; if ( eirq != 0 ) {