118 lines
3.2 KiB
Diff
118 lines
3.2 KiB
Diff
|
From 58d1ae79d144e6725a68fab99ef6a9b20b25a765 Mon Sep 17 00:00:00 2001
|
||
|
From: John Crispin <blogic@openwrt.org>
|
||
|
Date: Tue, 21 Feb 2012 21:09:01 +0100
|
||
|
Subject: [PATCH 37/70] 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.
|
||
|
|
||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||
|
---
|
||
|
arch/mips/lantiq/irq.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
arch/mips/lantiq/prom.c | 5 ++++
|
||
|
2 files changed, 66 insertions(+), 0 deletions(-)
|
||
|
|
||
|
--- a/arch/mips/lantiq/irq.c
|
||
|
+++ b/arch/mips/lantiq/irq.c
|
||
|
@@ -9,6 +9,7 @@
|
||
|
|
||
|
#include <linux/interrupt.h>
|
||
|
#include <linux/ioport.h>
|
||
|
+#include <linux/sched.h>
|
||
|
|
||
|
#include <asm/bootinfo.h>
|
||
|
#include <asm/irq_cpu.h>
|
||
|
@@ -54,6 +55,14 @@
|
||
|
#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
|
||
|
#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] = {
|
||
|
LTQ_EIU_IR0,
|
||
|
LTQ_EIU_IR1,
|
||
|
@@ -219,6 +228,47 @@ static void ltq_hw5_irqdispatch(void)
|
||
|
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)
|
||
|
{
|
||
|
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||
|
@@ -314,6 +364,17 @@ void __init arch_init_irq(void)
|
||
|
irq_set_chip_and_handler(i, <q_irq_type,
|
||
|
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)
|
||
|
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
|
||
|
IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
|
||
|
--- a/arch/mips/lantiq/prom.c
|
||
|
+++ b/arch/mips/lantiq/prom.c
|
||
|
@@ -108,4 +108,9 @@ void __init prom_init(void)
|
||
|
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
|
||
|
pr_info("SoC: %s\n", soc_info.sys_type);
|
||
|
prom_init_cmdline();
|
||
|
+
|
||
|
+#if defined(CONFIG_MIPS_MT_SMP)
|
||
|
+ if (register_vsmp_smp_ops())
|
||
|
+ panic("failed to register_vsmp_smp_ops()");
|
||
|
+#endif
|
||
|
}
|