aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/irq.c71
-rw-r--r--arch/powerpc/platforms/iseries/irq.c27
-rw-r--r--arch/powerpc/platforms/iseries/irq.h1
-rw-r--r--arch/powerpc/platforms/iseries/setup.c10
4 files changed, 44 insertions, 65 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5a71ed9612fe..9540c454ff02 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -78,10 +78,6 @@ EXPORT_SYMBOL(__irq_offset_value);
78 78
79static int ppc_spurious_interrupts; 79static int ppc_spurious_interrupts;
80 80
81#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
82extern void iSeries_smp_message_recv(struct pt_regs *);
83#endif
84
85#ifdef CONFIG_PPC32 81#ifdef CONFIG_PPC32
86#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 82#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
87 83
@@ -195,49 +191,6 @@ void fixup_irqs(cpumask_t map)
195} 191}
196#endif 192#endif
197 193
198#ifdef CONFIG_PPC_ISERIES
199void do_IRQ(struct pt_regs *regs)
200{
201 struct paca_struct *lpaca;
202
203 irq_enter();
204
205#ifdef CONFIG_DEBUG_STACKOVERFLOW
206 /* Debugging check for stack overflow: is there less than 2KB free? */
207 {
208 long sp;
209
210 sp = __get_SP() & (THREAD_SIZE-1);
211
212 if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
213 printk("do_IRQ: stack overflow: %ld\n",
214 sp - sizeof(struct thread_info));
215 dump_stack();
216 }
217 }
218#endif
219
220 lpaca = get_paca();
221#ifdef CONFIG_SMP
222 if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
223 lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
224 iSeries_smp_message_recv(regs);
225 }
226#endif /* CONFIG_SMP */
227 if (hvlpevent_is_pending())
228 process_hvlpevents(regs);
229
230 irq_exit();
231
232 if (lpaca->lppaca.int_dword.fields.decr_int) {
233 lpaca->lppaca.int_dword.fields.decr_int = 0;
234 /* Signal a fake decrementer interrupt */
235 timer_interrupt(regs);
236 }
237}
238
239#else /* CONFIG_PPC_ISERIES */
240
241void do_IRQ(struct pt_regs *regs) 194void do_IRQ(struct pt_regs *regs)
242{ 195{
243 int irq; 196 int irq;
@@ -286,16 +239,24 @@ void do_IRQ(struct pt_regs *regs)
286 } else 239 } else
287#endif 240#endif
288 __do_IRQ(irq, regs); 241 __do_IRQ(irq, regs);
289 } else 242 } else if (irq != -2)
290#ifdef CONFIG_PPC32 243 /* That's not SMP safe ... but who cares ? */
291 if (irq != -2) 244 ppc_spurious_interrupts++;
292#endif 245
293 /* That's not SMP safe ... but who cares ? */
294 ppc_spurious_interrupts++;
295 irq_exit(); 246 irq_exit();
296}
297 247
298#endif /* CONFIG_PPC_ISERIES */ 248#ifdef CONFIG_PPC_ISERIES
249 {
250 struct paca_struct *lpaca = get_paca();
251
252 if (lpaca->lppaca.int_dword.fields.decr_int) {
253 lpaca->lppaca.int_dword.fields.decr_int = 0;
254 /* Signal a fake decrementer interrupt */
255 timer_interrupt(regs);
256 }
257 }
258#endif
259}
299 260
300void __init init_IRQ(void) 261void __init init_IRQ(void)
301{ 262{
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 3bd576ecb288..5e92149b9b96 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -35,13 +35,19 @@
35#include <linux/irq.h> 35#include <linux/irq.h>
36#include <linux/spinlock.h> 36#include <linux/spinlock.h>
37 37
38#include <asm/paca.h>
38#include <asm/iseries/hv_types.h> 39#include <asm/iseries/hv_types.h>
39#include <asm/iseries/hv_lp_event.h> 40#include <asm/iseries/hv_lp_event.h>
40#include <asm/iseries/hv_call_xm.h> 41#include <asm/iseries/hv_call_xm.h>
42#include <asm/iseries/it_lp_queue.h>
41 43
42#include "irq.h" 44#include "irq.h"
43#include "call_pci.h" 45#include "call_pci.h"
44 46
47#if defined(CONFIG_SMP)
48extern void iSeries_smp_message_recv(struct pt_regs *);
49#endif
50
45enum pci_event_type { 51enum pci_event_type {
46 pe_bus_created = 0, /* PHB has been created */ 52 pe_bus_created = 0, /* PHB has been created */
47 pe_bus_error = 1, /* PHB has failed */ 53 pe_bus_error = 1, /* PHB has failed */
@@ -329,3 +335,24 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
329 irq_desc[virtirq].handler = &iSeries_IRQ_handler; 335 irq_desc[virtirq].handler = &iSeries_IRQ_handler;
330 return virtirq; 336 return virtirq;
331} 337}
338
339/*
340 * Get the next pending IRQ.
341 */
342int iSeries_get_irq(struct pt_regs *regs)
343{
344 struct paca_struct *lpaca;
345
346 lpaca = get_paca();
347#ifdef CONFIG_SMP
348 if (lpaca->lppaca.int_dword.fields.ipi_cnt) {
349 lpaca->lppaca.int_dword.fields.ipi_cnt = 0;
350 iSeries_smp_message_recv(regs);
351 }
352#endif /* CONFIG_SMP */
353 if (hvlpevent_is_pending())
354 process_hvlpevents(regs);
355
356 /* -2 means ignore this interrupt */
357 return -2;
358}
diff --git a/arch/powerpc/platforms/iseries/irq.h b/arch/powerpc/platforms/iseries/irq.h
index 5f643f16ecc0..b9c801ba5a47 100644
--- a/arch/powerpc/platforms/iseries/irq.h
+++ b/arch/powerpc/platforms/iseries/irq.h
@@ -4,5 +4,6 @@
4extern void iSeries_init_IRQ(void); 4extern void iSeries_init_IRQ(void);
5extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); 5extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
6extern void iSeries_activate_IRQs(void); 6extern void iSeries_activate_IRQs(void);
7extern int iSeries_get_irq(struct pt_regs *);
7 8
8#endif /* _ISERIES_IRQ_H */ 9#endif /* _ISERIES_IRQ_H */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index da26639190db..ad5ef80500ce 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -571,16 +571,6 @@ static void iSeries_show_cpuinfo(struct seq_file *m)
571 571
572/* 572/*
573 * Document me. 573 * Document me.
574 * and Implement me.
575 */
576static int iSeries_get_irq(struct pt_regs *regs)
577{
578 /* -2 means ignore this interrupt */
579 return -2;
580}
581
582/*
583 * Document me.
584 */ 574 */
585static void iSeries_restart(char *cmd) 575static void iSeries_restart(char *cmd)
586{ 576{