aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2011-04-21 00:20:24 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-21 19:44:45 -0400
commit01dae0f08dddf6ba86f956e60dceee4968f7a555 (patch)
tree5bf21fbff042da53d691ca834599dd7cde164669 /arch/sparc
parent5fcafb7a23e35b2f1a5243f4dd536240f52c8ceb (diff)
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: Daniel Hellstrom <daniel@gaisler.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/head_32.S27
-rw-r--r--arch/sparc/kernel/leon_kernel.c18
-rw-r--r--arch/sparc/kernel/leon_smp.c1
3 files changed, 21 insertions, 25 deletions
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 520c615d3766..587785759838 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -810,28 +810,25 @@ found_version:
810got_prop: 810got_prop:
811#ifdef CONFIG_SPARC_LEON 811#ifdef CONFIG_SPARC_LEON
812 /* no cpu-type check is needed, it is a SPARC-LEON */ 812 /* no cpu-type check is needed, it is a SPARC-LEON */
813#ifdef CONFIG_SMP
814 ba leon_smp_init
815 nop
816 813
817 .global leon_smp_init 814 sethi %hi(boot_cpu_id), %g2 ! boot-cpu index
818leon_smp_init:
819 /* let boot_cpu_id default to 0 (master always 0) */
820 815
821 rd %asr17,%g1 816#ifdef CONFIG_SMP
822 srl %g1,28,%g1 817 ldub [%g2 + %lo(boot_cpu_id)], %g1
818 cmp %g1, 0xff ! unset means first CPU
819 bne leon_smp_cpu_startup ! continue only with master
820 nop
821#endif
822 /* Get CPU-ID from most significant 4-bit of ASR17 */
823 rd %asr17, %g1
824 srl %g1, 28, %g1
823 825
824 cmp %g0,%g1 826 /* Update boot_cpu_id only on boot cpu */
825 beq sun4c_continue_boot !continue with master 827 stub %g1, [%g2 + %lo(boot_cpu_id)]
826 nop
827 828
828 ba leon_smp_cpu_startup
829 nop
830#else
831 ba sun4c_continue_boot 829 ba sun4c_continue_boot
832 nop 830 nop
833#endif 831#endif
834#endif
835 set cputypval, %o2 832 set cputypval, %o2
836 ldub [%o2 + 0x4], %l1 833 ldub [%o2 + 0x4], %l1
837 834
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index ab1458454422..8417a914e8a3 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -20,6 +20,7 @@
20#include <asm/traps.h> 20#include <asm/traps.h>
21#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
22#include <asm/smp.h> 22#include <asm/smp.h>
23#include <asm/setup.h>
23 24
24#include "prom.h" 25#include "prom.h"
25#include "irq.h" 26#include "irq.h"
@@ -53,7 +54,7 @@ static inline unsigned int leon_eirq_get(int cpu)
53static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) 54static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
54{ 55{
55 unsigned int eirq; 56 unsigned int eirq;
56 int cpu = hard_smp_processor_id(); 57 int cpu = sparc_leon3_cpuid();
57 58
58 eirq = leon_eirq_get(cpu); 59 eirq = leon_eirq_get(cpu);
59 if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ 60 if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */
@@ -79,8 +80,8 @@ void leon_eirq_setup(unsigned int eirq)
79 */ 80 */
80 irq_link(veirq); 81 irq_link(veirq);
81 mask = 1 << eirq; 82 mask = 1 << eirq;
82 oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(0)); 83 oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(boot_cpu_id));
83 LEON3_BYPASS_STORE_PA(LEON_IMASK(0), (oldmask | mask)); 84 LEON3_BYPASS_STORE_PA(LEON_IMASK(boot_cpu_id), (oldmask | mask));
84 sparc_leon_eirq = eirq; 85 sparc_leon_eirq = eirq;
85} 86}
86 87
@@ -106,12 +107,12 @@ static int irq_choose_cpu(const struct cpumask *affinity)
106 107
107 cpus_and(mask, cpu_online_map, *affinity); 108 cpus_and(mask, cpu_online_map, *affinity);
108 if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask)) 109 if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask))
109 return 0; 110 return boot_cpu_id;
110 else 111 else
111 return first_cpu(mask); 112 return first_cpu(mask);
112} 113}
113#else 114#else
114#define irq_choose_cpu(affinity) 0 115#define irq_choose_cpu(affinity) boot_cpu_id
115#endif 116#endif
116 117
117static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest, 118static 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 struct device_node *rootnp, *np, *nnp; 242 struct device_node *rootnp, *np, *nnp;
242 struct property *pp; 243 struct property *pp;
243 int len; 244 int len;
244 int cpu, icsel; 245 int icsel;
245 int ampopts; 246 int ampopts;
246 int err; 247 int err;
247 248
@@ -340,9 +341,8 @@ void __init leon_init_timers(irq_handler_t counter_fn)
340 * accessed anyway. 341 * accessed anyway.
341 * In AMP systems, Linux must run on CPU0 for the time being. 342 * In AMP systems, Linux must run on CPU0 for the time being.
342 */ 343 */
343 cpu = sparc_leon3_cpuid(); 344 icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[boot_cpu_id/8]);
344 icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]); 345 icsel = (icsel >> ((7 - (boot_cpu_id&0x7)) * 4)) & 0xf;
345 icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
346 leon3_irqctrl_regs += icsel; 346 leon3_irqctrl_regs += icsel;
347 347
348 /* Probe extended IRQ controller */ 348 /* Probe extended IRQ controller */
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index b4059dbb6d93..cbd8e31d01ff 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -50,7 +50,6 @@
50extern ctxd_t *srmmu_ctx_table_phys; 50extern ctxd_t *srmmu_ctx_table_phys;
51static int smp_processors_ready; 51static int smp_processors_ready;
52extern volatile unsigned long cpu_callin_map[NR_CPUS]; 52extern volatile unsigned long cpu_callin_map[NR_CPUS];
53extern unsigned char boot_cpu_id;
54extern cpumask_t smp_commenced_mask; 53extern cpumask_t smp_commenced_mask;
55void __init leon_configure_cache_smp(void); 54void __init leon_configure_cache_smp(void);
56 55