SW0 and SW1 interrupts are routed through GIC in EIC mode, implement get_sw_int hook for GIC and generic platform to create IRQ mapping for SW0 and SW1 in such mode. Tested-by: Serge Semin <fancer.lancer@xxxxxxxxx> Signed-off-by: Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx> --- arch/mips/generic/irq.c | 15 +++++++++++++++ arch/mips/include/asm/mips-gic.h | 10 ++++++++++ drivers/irqchip/irq-mips-gic.c | 15 +++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c index 933119262943..bc3599a76014 100644 --- a/arch/mips/generic/irq.c +++ b/arch/mips/generic/irq.c @@ -11,6 +11,7 @@ #include <linux/types.h> #include <asm/irq.h> +#include <asm/irq_cpu.h> #include <asm/mips-cps.h> #include <asm/time.h> @@ -59,3 +60,17 @@ unsigned int get_c0_compare_int(void) return mips_cpu_timer_irq; } + +int get_mips_sw_int(int hwint) +{ + int mips_sw_int_irq; + + if (mips_gic_present()) + mips_sw_int_irq = gic_get_sw_int(hwint); + else if (cpu_has_veic) + panic("Unimplemented!"); + else + mips_sw_int_irq = mips_cpu_get_sw_int(hwint); + + return mips_sw_int_irq; +} diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h index fd9da5e3beaa..3e9d1b252500 100644 --- a/arch/mips/include/asm/mips-gic.h +++ b/arch/mips/include/asm/mips-gic.h @@ -388,4 +388,14 @@ extern int gic_get_c0_perfcount_int(void); */ extern int gic_get_c0_fdc_int(void); +/** + * gic_get_sw_int() - Return software interrupt virq + * + * Determine the virq number to use for SWINT0 or SWINT1 interrupts, + * which may be routed via the GIC. + * + * Returns the virq number or a negative error number. + */ +extern int gic_get_sw_int(int hwirq); + #endif /* __MIPS_ASM_MIPS_CPS_H__ */ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 4c36e10ee2d3..7fa567677c00 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -152,6 +152,21 @@ int gic_get_c0_fdc_int(void) GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC)); } +int gic_get_sw_int(int hwint) +{ + int local_irq; + + WARN_ON(hwint > 1); + + local_irq = GIC_LOCAL_INT_SWINT0 + hwint; + + if (!gic_local_irq_is_routable(local_irq)) + return MIPS_CPU_IRQ_BASE + hwint; + + return irq_create_mapping(gic_irq_domain, + GIC_LOCAL_TO_HWIRQ(local_irq)); +} + static void gic_handle_shared_int(bool chained) { unsigned int intr; -- 2.46.0