Commit 01dae0f0 authored by Daniel Hellstrom's avatar Daniel Hellstrom Committed by David S. Miller

sparc32,leon: operate on boot-cpu IRQ controller registers

* proper initialization of boot_cpu_id (no hardcoding to 0)
 * use boot_cpu_id index to address into the IRQ controller where
   appropriate

Each CPU has a separate set of IRQ controller registers, this
patch makes sure that the boot-cpu registers are used instead
of CPU0's.
Signed-off-by: default avatarDaniel Hellstrom <daniel@gaisler.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5fcafb7a
...@@ -810,27 +810,24 @@ found_version: ...@@ -810,27 +810,24 @@ found_version:
got_prop: got_prop:
#ifdef CONFIG_SPARC_LEON #ifdef CONFIG_SPARC_LEON
/* no cpu-type check is needed, it is a SPARC-LEON */ /* no cpu-type check is needed, it is a SPARC-LEON */
#ifdef CONFIG_SMP
ba leon_smp_init
nop
.global leon_smp_init sethi %hi(boot_cpu_id), %g2 ! boot-cpu index
leon_smp_init:
/* let boot_cpu_id default to 0 (master always 0) */
rd %asr17,%g1 #ifdef CONFIG_SMP
srl %g1,28,%g1 ldub [%g2 + %lo(boot_cpu_id)], %g1
cmp %g1, 0xff ! unset means first CPU
bne leon_smp_cpu_startup ! continue only with master
nop
#endif
/* Get CPU-ID from most significant 4-bit of ASR17 */
rd %asr17, %g1
srl %g1, 28, %g1
cmp %g0,%g1 /* Update boot_cpu_id only on boot cpu */
beq sun4c_continue_boot !continue with master stub %g1, [%g2 + %lo(boot_cpu_id)]
nop
ba leon_smp_cpu_startup
nop
#else
ba sun4c_continue_boot ba sun4c_continue_boot
nop nop
#endif
#endif #endif
set cputypval, %o2 set cputypval, %o2
ldub [%o2 + 0x4], %l1 ldub [%o2 + 0x4], %l1
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/setup.h>
#include "prom.h" #include "prom.h"
#include "irq.h" #include "irq.h"
...@@ -53,7 +54,7 @@ static inline unsigned int leon_eirq_get(int cpu) ...@@ -53,7 +54,7 @@ static inline unsigned int leon_eirq_get(int cpu)
static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
{ {
unsigned int eirq; unsigned int eirq;
int cpu = hard_smp_processor_id(); int cpu = sparc_leon3_cpuid();
eirq = leon_eirq_get(cpu); eirq = leon_eirq_get(cpu);
if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */
...@@ -79,8 +80,8 @@ void leon_eirq_setup(unsigned int eirq) ...@@ -79,8 +80,8 @@ void leon_eirq_setup(unsigned int eirq)
*/ */
irq_link(veirq); irq_link(veirq);
mask = 1 << eirq; mask = 1 << eirq;
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(0)); oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(boot_cpu_id));
LEON3_BYPASS_STORE_PA(LEON_IMASK(0), (oldmask | mask)); LEON3_BYPASS_STORE_PA(LEON_IMASK(boot_cpu_id), (oldmask | mask));
sparc_leon_eirq = eirq; sparc_leon_eirq = eirq;
} }
...@@ -106,12 +107,12 @@ static int irq_choose_cpu(const struct cpumask *affinity) ...@@ -106,12 +107,12 @@ static int irq_choose_cpu(const struct cpumask *affinity)
cpus_and(mask, cpu_online_map, *affinity); cpus_and(mask, cpu_online_map, *affinity);
if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask)) if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask))
return 0; return boot_cpu_id;
else else
return first_cpu(mask); return first_cpu(mask);
} }
#else #else
#define irq_choose_cpu(affinity) 0 #define irq_choose_cpu(affinity) boot_cpu_id
#endif #endif
static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest, static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest,
...@@ -241,7 +242,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) ...@@ -241,7 +242,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
struct device_node *rootnp, *np, *nnp; struct device_node *rootnp, *np, *nnp;
struct property *pp; struct property *pp;
int len; int len;
int cpu, icsel; int icsel;
int ampopts; int ampopts;
int err; int err;
...@@ -340,9 +341,8 @@ void __init leon_init_timers(irq_handler_t counter_fn) ...@@ -340,9 +341,8 @@ void __init leon_init_timers(irq_handler_t counter_fn)
* accessed anyway. * accessed anyway.
* In AMP systems, Linux must run on CPU0 for the time being. * In AMP systems, Linux must run on CPU0 for the time being.
*/ */
cpu = sparc_leon3_cpuid(); icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[boot_cpu_id/8]);
icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]); icsel = (icsel >> ((7 - (boot_cpu_id&0x7)) * 4)) & 0xf;
icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
leon3_irqctrl_regs += icsel; leon3_irqctrl_regs += icsel;
/* Probe extended IRQ controller */ /* Probe extended IRQ controller */
......
...@@ -50,7 +50,6 @@ ...@@ -50,7 +50,6 @@
extern ctxd_t *srmmu_ctx_table_phys; extern ctxd_t *srmmu_ctx_table_phys;
static int smp_processors_ready; static int smp_processors_ready;
extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern volatile unsigned long cpu_callin_map[NR_CPUS];
extern unsigned char boot_cpu_id;
extern cpumask_t smp_commenced_mask; extern cpumask_t smp_commenced_mask;
void __init leon_configure_cache_smp(void); void __init leon_configure_cache_smp(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment