Remove unnecessary irq_mask_ack, irq_eoi, irq_disable, irq_enable irq_chip hooks for software interrupts, as they are simple edge triggered IRQs and there is no need for those duplicated callbacks. Don't mask IRQ in mips_mt_cpu_irq_ack, that is not expected for edge IRQ handling flow. Create a irq_chip for regular (non-MT) mode software interrupts, as they are edge triggered IRQs thus need startup/ack callbacks as well. Tested-by: Serge Semin <fancer.lancer@xxxxxxxxx> Signed-off-by: Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx> --- v4: - Reword commit message - Style fixes --- drivers/irqchip/irq-mips-cpu.c | 68 +++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c index 7b3501485d95..99f9151cc8e7 100644 --- a/drivers/irqchip/irq-mips-cpu.c +++ b/drivers/irqchip/irq-mips-cpu.c @@ -49,7 +49,7 @@ static inline void mask_mips_irq(struct irq_data *d) irq_disable_hazard(); } -static struct irq_chip mips_cpu_irq_controller = { +static const struct irq_chip mips_cpu_irq_controller = { .name = "MIPS", .irq_ack = mask_mips_irq, .irq_mask = mask_mips_irq, @@ -60,11 +60,33 @@ static struct irq_chip mips_cpu_irq_controller = { .irq_enable = unmask_mips_irq, }; +static unsigned int mips_sw_irq_startup(struct irq_data *d) +{ + clear_c0_cause(C_SW0 << d->hwirq); + back_to_back_c0_hazard(); + unmask_mips_irq(d); + return 0; +} + +static void mips_sw_irq_ack(struct irq_data *d) +{ + clear_c0_cause(C_SW0 << d->hwirq); + back_to_back_c0_hazard(); +} + +static const struct irq_chip mips_cpu_sw_irq_controller = { + .name = "MIPS", + .irq_startup = mips_sw_irq_startup, + .irq_ack = mips_sw_irq_ack, + .irq_mask = mask_mips_irq, + .irq_unmask = unmask_mips_irq, +}; + +#ifdef CONFIG_MIPS_MT /* * Basically the same as above but taking care of all the MT stuff */ - -static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d) +static unsigned int mips_mt_sw_irq_startup(struct irq_data *d) { unsigned int vpflags = dvpe(); @@ -76,14 +98,14 @@ static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d) /* * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for mips_cpu_irq_end. + * to deal with concurrency issues. */ -static void mips_mt_cpu_irq_ack(struct irq_data *d) +static void mips_mt_sw_irq_ack(struct irq_data *d) { unsigned int vpflags = dvpe(); + clear_c0_cause(C_SW0 << d->hwirq); evpe(vpflags); - mask_mips_irq(d); } #ifdef CONFIG_GENERIC_IRQ_IPI @@ -108,21 +130,17 @@ static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu) } #endif /* CONFIG_GENERIC_IRQ_IPI */ - -static struct irq_chip mips_mt_cpu_irq_controller = { +static const struct irq_chip mips_mt_cpu_irq_controller = { .name = "MIPS", - .irq_startup = mips_mt_cpu_irq_startup, - .irq_ack = mips_mt_cpu_irq_ack, + .irq_startup = mips_mt_sw_irq_startup, + .irq_ack = mips_mt_sw_irq_ack, .irq_mask = mask_mips_irq, - .irq_mask_ack = mips_mt_cpu_irq_ack, .irq_unmask = unmask_mips_irq, - .irq_eoi = unmask_mips_irq, - .irq_disable = mask_mips_irq, - .irq_enable = unmask_mips_irq, #ifdef CONFIG_GENERIC_IRQ_IPI .ipi_send_single = mips_mt_send_ipi, #endif }; +#endif asmlinkage void __weak plat_irq_dispatch(void) { @@ -149,17 +167,27 @@ asmlinkage void __weak plat_irq_dispatch(void) } } +#ifdef CONFIG_MIPS_MT +static inline const struct irq_chip *mips_cpu_get_sw_irqchip(void) +{ + return cpu_has_mipsmt ? &mips_mt_cpu_sw_irq_controller : &mips_cpu_sw_irq_controller; +} +#else +static inline const struct irq_chip *mips_cpu_get_sw_irqchip(void) +{ + return &mips_cpu_sw_irq_controller; +} +#endif + static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - struct irq_chip *chip; + const struct irq_chip *chip; - if (hw < 2 && cpu_has_mipsmt) { - /* Software interrupts are used for MT/CMT IPI */ - chip = &mips_mt_cpu_irq_controller; - } else { + if (hw < 2) + chip = mips_cpu_get_sw_irqchip(); + else chip = &mips_cpu_irq_controller; - } if (cpu_has_vint) set_vi_handler(hw, plat_irq_dispatch); -- 2.46.0