|
@@ -379,32 +379,32 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = {
|
|
|
|
|
|
static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
|
|
static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
|
|
|
|
|
|
-#if defined(CONFIG_MIPS_MT_SMP)
|
|
|
|
/*
|
|
/*
|
|
* This GIC specific tabular array defines the association between External
|
|
* This GIC specific tabular array defines the association between External
|
|
* Interrupts and CPUs/Core Interrupts. The nature of the External
|
|
* Interrupts and CPUs/Core Interrupts. The nature of the External
|
|
* Interrupts is also defined here - polarity/trigger.
|
|
* Interrupts is also defined here - polarity/trigger.
|
|
*/
|
|
*/
|
|
|
|
+
|
|
|
|
+#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
|
|
static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
|
|
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 },
|
|
|
|
- { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { GIC_EXT_INTR(10), X, X, X, X, 0 },
|
|
|
|
- { GIC_EXT_INTR(11), X, X, X, X, 0 },
|
|
|
|
- { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 },
|
|
|
|
- { 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 },
|
|
|
|
-/* This is the end of the general interrupts now we do IPI ones */
|
|
|
|
|
|
+ { X, X, X, X, 0 },
|
|
|
|
+ { X, X, X, X, 0 },
|
|
|
|
+ { X, X, X, X, 0 },
|
|
|
|
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { X, X, X, X, 0 },
|
|
|
|
+ { X, X, X, X, 0 },
|
|
|
|
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
|
|
|
+ { X, X, X, X, 0 },
|
|
|
|
+ /* The remainder of this table is initialised by fill_ipi_map */
|
|
};
|
|
};
|
|
-#endif
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* GCMP needs to be detected before any SMP initialisation
|
|
* GCMP needs to be detected before any SMP initialisation
|
|
@@ -419,20 +419,35 @@ int __init gcmp_probe(unsigned long addr, unsigned long size)
|
|
gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
|
|
gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
|
|
|
|
|
|
if (gcmp_present)
|
|
if (gcmp_present)
|
|
- printk(KERN_DEBUG "GCMP present\n");
|
|
|
|
|
|
+ pr_debug("GCMP present\n");
|
|
return gcmp_present;
|
|
return gcmp_present;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Return the number of IOCU's present */
|
|
|
|
+int __init gcmp_niocu(void)
|
|
|
|
+{
|
|
|
|
+ return gcmp_present ?
|
|
|
|
+ (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF :
|
|
|
|
+ 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Set GCMP region attributes */
|
|
|
|
+void __init gcmp_setregion(int region, unsigned long base,
|
|
|
|
+ unsigned long mask, int type)
|
|
|
|
+{
|
|
|
|
+ GCMPGCBn(CMxBASE, region) = base;
|
|
|
|
+ GCMPGCBn(CMxMASK, region) = mask | type;
|
|
|
|
+}
|
|
|
|
+
|
|
#if defined(CONFIG_MIPS_MT_SMP)
|
|
#if defined(CONFIG_MIPS_MT_SMP)
|
|
static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
|
|
static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
|
|
{
|
|
{
|
|
int intr = baseintr + cpu;
|
|
int intr = baseintr + cpu;
|
|
- gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr);
|
|
|
|
gic_intr_map[intr].cpunum = cpu;
|
|
gic_intr_map[intr].cpunum = cpu;
|
|
gic_intr_map[intr].pin = cpupin;
|
|
gic_intr_map[intr].pin = cpupin;
|
|
gic_intr_map[intr].polarity = GIC_POL_POS;
|
|
gic_intr_map[intr].polarity = GIC_POL_POS;
|
|
gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
|
|
gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
|
|
- gic_intr_map[intr].ipiflag = 1;
|
|
|
|
|
|
+ gic_intr_map[intr].flags = GIC_FLAG_IPI;
|
|
ipi_map[cpu] |= (1 << (cpupin + 2));
|
|
ipi_map[cpu] |= (1 << (cpupin + 2));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -447,6 +462,12 @@ static void __init fill_ipi_map(void)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+void __init arch_init_ipiirq(int irq, struct irqaction *action)
|
|
|
|
+{
|
|
|
|
+ setup_irq(irq, action);
|
|
|
|
+ set_irq_handler(irq, handle_percpu_irq);
|
|
|
|
+}
|
|
|
|
+
|
|
void __init arch_init_irq(void)
|
|
void __init arch_init_irq(void)
|
|
{
|
|
{
|
|
init_i8259_irqs();
|
|
init_i8259_irqs();
|
|
@@ -463,7 +484,7 @@ void __init arch_init_irq(void)
|
|
MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF;
|
|
MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF;
|
|
}
|
|
}
|
|
if (gic_present)
|
|
if (gic_present)
|
|
- printk(KERN_DEBUG "GIC present\n");
|
|
|
|
|
|
+ pr_debug("GIC present\n");
|
|
|
|
|
|
switch (mips_revision_sconid) {
|
|
switch (mips_revision_sconid) {
|
|
case MIPS_REVISION_SCON_SOCIT:
|
|
case MIPS_REVISION_SCON_SOCIT:
|
|
@@ -526,16 +547,16 @@ void __init arch_init_irq(void)
|
|
&corehi_irqaction);
|
|
&corehi_irqaction);
|
|
}
|
|
}
|
|
|
|
|
|
-#if defined(CONFIG_MIPS_MT_SMP)
|
|
|
|
if (gic_present) {
|
|
if (gic_present) {
|
|
/* FIXME */
|
|
/* FIXME */
|
|
int i;
|
|
int i;
|
|
-
|
|
|
|
|
|
+#if defined(CONFIG_MIPS_MT_SMP)
|
|
gic_call_int_base = GIC_NUM_INTRS - NR_CPUS;
|
|
gic_call_int_base = GIC_NUM_INTRS - NR_CPUS;
|
|
gic_resched_int_base = gic_call_int_base - NR_CPUS;
|
|
gic_resched_int_base = gic_call_int_base - NR_CPUS;
|
|
-
|
|
|
|
fill_ipi_map();
|
|
fill_ipi_map();
|
|
- gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
|
|
|
|
|
|
+#endif
|
|
|
|
+ gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
|
|
|
|
+ ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
|
|
if (!gcmp_present) {
|
|
if (!gcmp_present) {
|
|
/* Enable the GIC */
|
|
/* Enable the GIC */
|
|
i = REG(_msc01_biu_base, MSC01_SC_CFG);
|
|
i = REG(_msc01_biu_base, MSC01_SC_CFG);
|
|
@@ -543,7 +564,7 @@ void __init arch_init_irq(void)
|
|
(i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
|
|
(i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
|
|
pr_debug("GIC Enabled\n");
|
|
pr_debug("GIC Enabled\n");
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+#if defined(CONFIG_MIPS_MT_SMP)
|
|
/* set up ipi interrupts */
|
|
/* set up ipi interrupts */
|
|
if (cpu_has_vint) {
|
|
if (cpu_has_vint) {
|
|
set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
|
|
set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
|
|
@@ -556,16 +577,14 @@ void __init arch_init_irq(void)
|
|
write_c0_status(0x1100dc00);
|
|
write_c0_status(0x1100dc00);
|
|
printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
|
|
printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
|
|
for (i = 0; i < NR_CPUS; i++) {
|
|
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);
|
|
|
|
|
|
+ arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
|
|
|
|
+ GIC_RESCHED_INT(i), &irq_resched);
|
|
|
|
+ arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
|
|
|
|
+ GIC_CALL_INT(i), &irq_call);
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
} else {
|
|
} else {
|
|
|
|
+#if defined(CONFIG_MIPS_MT_SMP)
|
|
/* set up ipi interrupts */
|
|
/* set up ipi interrupts */
|
|
if (cpu_has_veic) {
|
|
if (cpu_has_veic) {
|
|
set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch);
|
|
set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch);
|
|
@@ -580,14 +599,10 @@ void __init arch_init_irq(void)
|
|
cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
|
|
cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
|
|
cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
|
|
cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
|
|
}
|
|
}
|
|
-
|
|
|
|
- setup_irq(cpu_ipi_resched_irq, &irq_resched);
|
|
|
|
- setup_irq(cpu_ipi_call_irq, &irq_call);
|
|
|
|
-
|
|
|
|
- set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
|
|
|
|
- set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
|
|
|
|
- }
|
|
|
|
|
|
+ arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
|
|
|
|
+ arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
|
|
#endif
|
|
#endif
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void malta_be_init(void)
|
|
void malta_be_init(void)
|