Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a214cef9 authored by Tim Anderson's avatar Tim Anderson Committed by Ralf Baechle
Browse files

MIPS: CMP: Extend IPI handling to CPU number



This takes the current IPI interrupt assignment from the fix number of 4
to the number of CPUs defined in the system.

Signed-off-by: default avatarTim Anderson <tanderson@mvista.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 9306c8de
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -247,6 +247,10 @@ static void __init gic_basic_init(void)
		if (cpu == X)
			continue;

		if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 &&
					_intrmap[i].ipiflag == 0)
			continue;

		setup_intr(_intrmap[i].intrnum,
				_intrmap[i].cpunum,
				_intrmap[i].pin,
+36 −38
Original line number Diff line number Diff line
@@ -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 */