aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/irq_cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/irq_cpu.c')
-rw-r--r--arch/mips/kernel/irq_cpu.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index e498f2b3646a..590c2c980fd3 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -36,6 +36,7 @@
36#include <asm/irq_cpu.h> 36#include <asm/irq_cpu.h>
37#include <asm/mipsregs.h> 37#include <asm/mipsregs.h>
38#include <asm/mipsmtregs.h> 38#include <asm/mipsmtregs.h>
39#include <asm/setup.h>
39 40
40static inline void unmask_mips_irq(struct irq_data *d) 41static inline void unmask_mips_irq(struct irq_data *d)
41{ 42{
@@ -94,28 +95,24 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
94 .irq_eoi = unmask_mips_irq, 95 .irq_eoi = unmask_mips_irq,
95}; 96};
96 97
97void __init mips_cpu_irq_init(void) 98asmlinkage void __weak plat_irq_dispatch(void)
98{ 99{
99 int irq_base = MIPS_CPU_IRQ_BASE; 100 unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM;
100 int i; 101 int irq;
101 102
102 /* Mask interrupts. */ 103 if (!pending) {
103 clear_c0_status(ST0_IM); 104 spurious_interrupt();
104 clear_c0_cause(CAUSEF_IP); 105 return;
105 106 }
106 /* Software interrupts are used for MT/CMT IPI */
107 for (i = irq_base; i < irq_base + 2; i++)
108 irq_set_chip_and_handler(i, cpu_has_mipsmt ?
109 &mips_mt_cpu_irq_controller :
110 &mips_cpu_irq_controller,
111 handle_percpu_irq);
112 107
113 for (i = irq_base + 2; i < irq_base + 8; i++) 108 pending >>= CAUSEB_IP;
114 irq_set_chip_and_handler(i, &mips_cpu_irq_controller, 109 while (pending) {
115 handle_percpu_irq); 110 irq = fls(pending) - 1;
111 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
112 pending &= ~BIT(irq);
113 }
116} 114}
117 115
118#ifdef CONFIG_IRQ_DOMAIN
119static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, 116static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
120 irq_hw_number_t hw) 117 irq_hw_number_t hw)
121{ 118{
@@ -128,6 +125,9 @@ static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
128 chip = &mips_cpu_irq_controller; 125 chip = &mips_cpu_irq_controller;
129 } 126 }
130 127
128 if (cpu_has_vint)
129 set_vi_handler(hw, plat_irq_dispatch);
130
131 irq_set_chip_and_handler(irq, chip, handle_percpu_irq); 131 irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
132 132
133 return 0; 133 return 0;
@@ -138,8 +138,7 @@ static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
138 .xlate = irq_domain_xlate_onecell, 138 .xlate = irq_domain_xlate_onecell,
139}; 139};
140 140
141int __init mips_cpu_intc_init(struct device_node *of_node, 141static void __init __mips_cpu_irq_init(struct device_node *of_node)
142 struct device_node *parent)
143{ 142{
144 struct irq_domain *domain; 143 struct irq_domain *domain;
145 144
@@ -151,7 +150,16 @@ int __init mips_cpu_intc_init(struct device_node *of_node,
151 &mips_cpu_intc_irq_domain_ops, NULL); 150 &mips_cpu_intc_irq_domain_ops, NULL);
152 if (!domain) 151 if (!domain)
153 panic("Failed to add irqdomain for MIPS CPU"); 152 panic("Failed to add irqdomain for MIPS CPU");
153}
154 154
155void __init mips_cpu_irq_init(void)
156{
157 __mips_cpu_irq_init(NULL);
158}
159
160int __init mips_cpu_irq_of_init(struct device_node *of_node,
161 struct device_node *parent)
162{
163 __mips_cpu_irq_init(of_node);
155 return 0; 164 return 0;
156} 165}
157#endif /* CONFIG_IRQ_DOMAIN */