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

Commit a8d096ef authored by John Crispin's avatar John Crispin Committed by Ralf Baechle
Browse files

MIPS: lantiq: add ipi handlers to make vsmp work



Add IPI handlers to the interrupt code. This patch makes MIPS_MT_SMP work
on lantiq socs. The code is based on the malta implementation.

Signed-off-by: default avatarJohn Crispin <blogic@openwrt.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/3704/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 59c11579
Loading
Loading
Loading
Loading
+60 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,14 @@
#define ltq_eiu_w32(x, y)	ltq_w32((x), ltq_eiu_membase + (y))
#define ltq_eiu_w32(x, y)	ltq_w32((x), ltq_eiu_membase + (y))
#define ltq_eiu_r32(x)		ltq_r32(ltq_eiu_membase + (x))
#define ltq_eiu_r32(x)		ltq_r32(ltq_eiu_membase + (x))


/* our 2 ipi interrupts for VSMP */
#define MIPS_CPU_IPI_RESCHED_IRQ	0
#define MIPS_CPU_IPI_CALL_IRQ		1

#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
int gic_present;
#endif

static unsigned short ltq_eiu_irq[MAX_EIU] = {
static unsigned short ltq_eiu_irq[MAX_EIU] = {
	LTQ_EIU_IR0,
	LTQ_EIU_IR0,
	LTQ_EIU_IR1,
	LTQ_EIU_IR1,
@@ -219,6 +227,47 @@ static void ltq_hw5_irqdispatch(void)
	do_IRQ(MIPS_CPU_TIMER_IRQ);
	do_IRQ(MIPS_CPU_TIMER_IRQ);
}
}


#ifdef CONFIG_MIPS_MT_SMP
void __init arch_init_ipiirq(int irq, struct irqaction *action)
{
	setup_irq(irq, action);
	irq_set_handler(irq, handle_percpu_irq);
}

static void ltq_sw0_irqdispatch(void)
{
	do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
}

static void ltq_sw1_irqdispatch(void)
{
	do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
}
static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
{
	scheduler_ipi();
	return IRQ_HANDLED;
}

static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
{
	smp_call_function_interrupt();
	return IRQ_HANDLED;
}

static struct irqaction irq_resched = {
	.handler	= ipi_resched_interrupt,
	.flags		= IRQF_PERCPU,
	.name		= "IPI_resched"
};

static struct irqaction irq_call = {
	.handler	= ipi_call_interrupt,
	.flags		= IRQF_PERCPU,
	.name		= "IPI_call"
};
#endif

asmlinkage void plat_irq_dispatch(void)
asmlinkage void plat_irq_dispatch(void)
{
{
	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
@@ -312,6 +361,17 @@ void __init arch_init_irq(void)
			irq_set_chip_and_handler(i, &ltq_irq_type,
			irq_set_chip_and_handler(i, &ltq_irq_type,
				handle_level_irq);
				handle_level_irq);


#if defined(CONFIG_MIPS_MT_SMP)
	if (cpu_has_vint) {
		pr_info("Setting up IPI vectored interrupts\n");
		set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
		set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
	}
	arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
		&irq_resched);
	arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
#endif

#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
	set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
	set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
		IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
		IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+5 −0
Original line number Original line Diff line number Diff line
@@ -68,4 +68,9 @@ void __init prom_init(void)
	soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
	soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
	pr_info("SoC: %s\n", soc_info.sys_type);
	pr_info("SoC: %s\n", soc_info.sys_type);
	prom_init_cmdline();
	prom_init_cmdline();

#if defined(CONFIG_MIPS_MT_SMP)
	if (register_vsmp_smp_ops())
		panic("failed to register_vsmp_smp_ops()");
#endif
}
}