|
@@ -331,6 +331,11 @@ static struct irqaction irq_call = {
|
|
|
.flags = IRQF_DISABLED|IRQF_PERCPU,
|
|
|
.name = "IPI_call"
|
|
|
};
|
|
|
+
|
|
|
+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))
|
|
|
#endif /* CONFIG_MIPS_MT_SMP */
|
|
|
|
|
|
static struct irqaction i8259irq = {
|
|
@@ -370,7 +375,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 },
|
|
@@ -387,14 +392,7 @@ 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
|
|
|
|
|
@@ -416,14 +414,25 @@ 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
|
|
@@ -514,24 +523,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) {
|
|
@@ -553,12 +548,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 */
|