diff options
Diffstat (limited to 'arch/mips/mti-malta/malta-int.c')
-rw-r--r-- | arch/mips/mti-malta/malta-int.c | 90 |
1 files changed, 48 insertions, 42 deletions
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index ea176113fea..3e0a9b35ba5 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/sched.h> +#include <linux/smp.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -332,6 +333,21 @@ static struct irqaction irq_call = { }; #endif /* CONFIG_MIPS_MT_SMP */ +static int gic_resched_int_base; +static int gic_call_int_base; +#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) +#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) + +unsigned int plat_ipi_call_int_xlate(unsigned int cpu) +{ + return GIC_CALL_INT(cpu); +} + +unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) +{ + return GIC_RESCHED_INT(cpu); +} + static struct irqaction i8259irq = { .handler = no_action, .name = "XT-PIC cascade" @@ -369,7 +385,7 @@ static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); * Interrupts and CPUs/Core Interrupts. The nature of the External * Interrupts is also defined here - polarity/trigger. */ -static struct gic_intr_map gic_intr_map[] = { +static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { { GIC_EXT_INTR(0), X, X, X, X, 0 }, { GIC_EXT_INTR(1), X, X, X, X, 0 }, { GIC_EXT_INTR(2), X, X, X, X, 0 }, @@ -386,21 +402,14 @@ static struct gic_intr_map gic_intr_map[] = { { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { GIC_EXT_INTR(15), X, X, X, X, 0 }, - { GIC_EXT_INTR(16), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(17), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(18), 1, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(19), 1, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(20), 2, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(21), 2, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(22), 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(23), 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, +/* This is the end of the general interrupts now we do IPI ones */ }; #endif /* * GCMP needs to be detected before any SMP initialisation */ -static int __init gcmp_probe(unsigned long addr, unsigned long size) +int __init gcmp_probe(unsigned long addr, unsigned long size) { if (gcmp_present >= 0) return gcmp_present; @@ -415,28 +424,36 @@ static int __init gcmp_probe(unsigned long addr, unsigned long size) } #if defined(CONFIG_MIPS_MT_SMP) +static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) +{ + int intr = baseintr + cpu; + gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr); + gic_intr_map[intr].cpunum = cpu; + gic_intr_map[intr].pin = cpupin; + gic_intr_map[intr].polarity = GIC_POL_POS; + gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; + gic_intr_map[intr].ipiflag = 1; + ipi_map[cpu] |= (1 << (cpupin + 2)); +} + static void __init fill_ipi_map(void) { - int i; + int cpu; - for (i = 0; i < ARRAY_SIZE(gic_intr_map); i++) { - if (gic_intr_map[i].ipiflag && (gic_intr_map[i].cpunum != X)) - ipi_map[gic_intr_map[i].cpunum] |= - (1 << (gic_intr_map[i].pin + 2)); + for (cpu = 0; cpu < NR_CPUS; cpu++) { + fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); + fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); } } #endif void __init arch_init_irq(void) { - int gic_present, gcmp_present; - init_i8259_irqs(); if (!cpu_has_veic) mips_cpu_irq_init(); - gcmp_present = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); if (gcmp_present) { GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; gic_present = 1; @@ -513,24 +530,10 @@ void __init arch_init_irq(void) if (gic_present) { /* FIXME */ int i; - struct { - unsigned int resched; - unsigned int call; - } ipiirq[] = { - { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE0, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE0}, - { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE1, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE1 - }, { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE2, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE2 - }, { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE3, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE3 - } - }; + + gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; + gic_resched_int_base = gic_call_int_base - NR_CPUS; + fill_ipi_map(); gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); if (!gcmp_present) { @@ -552,12 +555,15 @@ void __init arch_init_irq(void) printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); write_c0_status(0x1100dc00); printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); - for (i = 0; i < ARRAY_SIZE(ipiirq); i++) { - setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, &irq_resched); - setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].call, &irq_call); - - set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, handle_percpu_irq); - set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].call, handle_percpu_irq); + for (i = 0; i < NR_CPUS; i++) { + setup_irq(MIPS_GIC_IRQ_BASE + + GIC_RESCHED_INT(i), &irq_resched); + setup_irq(MIPS_GIC_IRQ_BASE + + GIC_CALL_INT(i), &irq_call); + set_irq_handler(MIPS_GIC_IRQ_BASE + + GIC_RESCHED_INT(i), handle_percpu_irq); + set_irq_handler(MIPS_GIC_IRQ_BASE + + GIC_CALL_INT(i), handle_percpu_irq); } } else { /* set up ipi interrupts */ |