aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/common/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic/common/irq.c')
-rw-r--r--arch/mips/netlogic/common/irq.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
index e52bfcbce093..4d6bd8f6ee29 100644
--- a/arch/mips/netlogic/common/irq.c
+++ b/arch/mips/netlogic/common/irq.c
@@ -70,33 +70,34 @@
70 */ 70 */
71 71
72/* Globals */ 72/* Globals */
73static uint64_t nlm_irq_mask;
74static DEFINE_SPINLOCK(nlm_pic_lock);
75
76static void xlp_pic_enable(struct irq_data *d) 73static void xlp_pic_enable(struct irq_data *d)
77{ 74{
78 unsigned long flags; 75 unsigned long flags;
76 struct nlm_soc_info *nodep;
79 int irt; 77 int irt;
80 78
79 nodep = nlm_current_node();
81 irt = nlm_irq_to_irt(d->irq); 80 irt = nlm_irq_to_irt(d->irq);
82 if (irt == -1) 81 if (irt == -1)
83 return; 82 return;
84 spin_lock_irqsave(&nlm_pic_lock, flags); 83 spin_lock_irqsave(&nodep->piclock, flags);
85 nlm_pic_enable_irt(nlm_pic_base, irt); 84 nlm_pic_enable_irt(nodep->picbase, irt);
86 spin_unlock_irqrestore(&nlm_pic_lock, flags); 85 spin_unlock_irqrestore(&nodep->piclock, flags);
87} 86}
88 87
89static void xlp_pic_disable(struct irq_data *d) 88static void xlp_pic_disable(struct irq_data *d)
90{ 89{
90 struct nlm_soc_info *nodep;
91 unsigned long flags; 91 unsigned long flags;
92 int irt; 92 int irt;
93 93
94 nodep = nlm_current_node();
94 irt = nlm_irq_to_irt(d->irq); 95 irt = nlm_irq_to_irt(d->irq);
95 if (irt == -1) 96 if (irt == -1)
96 return; 97 return;
97 spin_lock_irqsave(&nlm_pic_lock, flags); 98 spin_lock_irqsave(&nodep->piclock, flags);
98 nlm_pic_disable_irt(nlm_pic_base, irt); 99 nlm_pic_disable_irt(nodep->picbase, irt);
99 spin_unlock_irqrestore(&nlm_pic_lock, flags); 100 spin_unlock_irqrestore(&nodep->piclock, flags);
100} 101}
101 102
102static void xlp_pic_mask_ack(struct irq_data *d) 103static void xlp_pic_mask_ack(struct irq_data *d)
@@ -109,8 +110,10 @@ static void xlp_pic_mask_ack(struct irq_data *d)
109static void xlp_pic_unmask(struct irq_data *d) 110static void xlp_pic_unmask(struct irq_data *d)
110{ 111{
111 void *hd = irq_data_get_irq_handler_data(d); 112 void *hd = irq_data_get_irq_handler_data(d);
113 struct nlm_soc_info *nodep;
112 int irt; 114 int irt;
113 115
116 nodep = nlm_current_node();
114 irt = nlm_irq_to_irt(d->irq); 117 irt = nlm_irq_to_irt(d->irq);
115 if (irt == -1) 118 if (irt == -1)
116 return; 119 return;
@@ -120,7 +123,7 @@ static void xlp_pic_unmask(struct irq_data *d)
120 extra_ack(d); 123 extra_ack(d);
121 } 124 }
122 /* Ack is a single write, no need to lock */ 125 /* Ack is a single write, no need to lock */
123 nlm_pic_ack(nlm_pic_base, irt); 126 nlm_pic_ack(nodep->picbase, irt);
124} 127}
125 128
126static struct irq_chip xlp_pic = { 129static struct irq_chip xlp_pic = {
@@ -177,7 +180,11 @@ struct irq_chip nlm_cpu_intr = {
177void __init init_nlm_common_irqs(void) 180void __init init_nlm_common_irqs(void)
178{ 181{
179 int i, irq, irt; 182 int i, irq, irt;
183 uint64_t irqmask;
184 struct nlm_soc_info *nodep;
180 185
186 nodep = nlm_current_node();
187 irqmask = (1ULL << IRQ_TIMER);
181 for (i = 0; i < PIC_IRT_FIRST_IRQ; i++) 188 for (i = 0; i < PIC_IRT_FIRST_IRQ; i++)
182 irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq); 189 irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq);
183 190
@@ -189,7 +196,7 @@ void __init init_nlm_common_irqs(void)
189 nlm_smp_function_ipi_handler); 196 nlm_smp_function_ipi_handler);
190 irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr, 197 irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
191 nlm_smp_resched_ipi_handler); 198 nlm_smp_resched_ipi_handler);
192 nlm_irq_mask |= 199 irqmask |=
193 ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE)); 200 ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
194#endif 201#endif
195 202
@@ -197,11 +204,11 @@ void __init init_nlm_common_irqs(void)
197 irt = nlm_irq_to_irt(irq); 204 irt = nlm_irq_to_irt(irq);
198 if (irt == -1) 205 if (irt == -1)
199 continue; 206 continue;
200 nlm_irq_mask |= (1ULL << irq); 207 irqmask |= (1ULL << irq);
201 nlm_pic_init_irt(nlm_pic_base, irt, irq, 0); 208 nlm_pic_init_irt(nodep->picbase, irt, irq, 0);
202 } 209 }
203 210
204 nlm_irq_mask |= (1ULL << IRQ_TIMER); 211 nodep->irqmask = irqmask;
205} 212}
206 213
207void __init arch_init_irq(void) 214void __init arch_init_irq(void)
@@ -209,29 +216,39 @@ void __init arch_init_irq(void)
209 /* Initialize the irq descriptors */ 216 /* Initialize the irq descriptors */
210 init_nlm_common_irqs(); 217 init_nlm_common_irqs();
211 218
212 write_c0_eimr(nlm_irq_mask); 219 write_c0_eimr(nlm_current_node()->irqmask);
213} 220}
214 221
215void __cpuinit nlm_smp_irq_init(void) 222void __cpuinit nlm_smp_irq_init(void)
216{ 223{
217 /* set interrupt mask for non-zero cpus */ 224 /* set interrupt mask for non-zero cpus */
218 write_c0_eimr(nlm_irq_mask); 225 write_c0_eimr(nlm_current_node()->irqmask);
219} 226}
220 227
221asmlinkage void plat_irq_dispatch(void) 228asmlinkage void plat_irq_dispatch(void)
222{ 229{
223 uint64_t eirr; 230 uint64_t eirr;
224 int i; 231 int i, node;
225 232
233 node = nlm_nodeid();
226 eirr = read_c0_eirr() & read_c0_eimr(); 234 eirr = read_c0_eirr() & read_c0_eimr();
227 if (eirr & (1 << IRQ_TIMER)) { 235 if (eirr & (1 << IRQ_TIMER)) {
228 do_IRQ(IRQ_TIMER); 236 do_IRQ(IRQ_TIMER);
229 return; 237 return;
230 } 238 }
231 239#ifdef CONFIG_SMP
240 if (eirr & IRQ_IPI_SMP_FUNCTION) {
241 do_IRQ(IRQ_IPI_SMP_FUNCTION);
242 return;
243 }
244 if (eirr & IRQ_IPI_SMP_RESCHEDULE) {
245 do_IRQ(IRQ_IPI_SMP_RESCHEDULE);
246 return;
247 }
248#endif
232 i = __ilog2_u64(eirr); 249 i = __ilog2_u64(eirr);
233 if (i == -1) 250 if (i == -1)
234 return; 251 return;
235 252
236 do_IRQ(i); 253 do_IRQ(nlm_irq_to_xirq(node, i));
237} 254}