diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2005-11-17 18:04:37 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-09 14:50:18 +1100 |
commit | 1d7a6b97f3c30087e307655116ff2ed492a37ad0 (patch) | |
tree | 7a384f6fac7ea5328ea0c2d3f96368e9bc3a4fc9 /arch | |
parent | a50b56d24c59db33792b421af4016a9c958a906f (diff) |
powerpc: more iseries irq work
Make get_IRQ return a pending irq number so it can be handled
in the powerpc geeneric code.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/iseries/irq.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 5e92149b9b96..42e978e4897a 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -82,31 +82,29 @@ struct pci_event { } data; }; +static DEFINE_SPINLOCK(pending_irqs_lock); +static int num_pending_irqs; +static int pending_irqs[NR_IRQS]; + static void int_received(struct pci_event *event, struct pt_regs *regs) { int irq; -#ifdef CONFIG_IRQSTACKS - struct thread_info *curtp, *irqtp; -#endif switch (event->event.xSubtype) { case pe_slot_interrupt: irq = event->event.xCorrelationToken; - /* Dispatch the interrupt handlers for this irq */ -#ifdef CONFIG_IRQSTACKS - /* Switch to the irq stack to handle this */ - curtp = current_thread_info(); - irqtp = hardirq_ctx[smp_processor_id()]; - if (curtp != irqtp) { - irqtp->task = curtp->task; - irqtp->flags = 0; - call___do_IRQ(irq, regs, irqtp); - irqtp->task = NULL; - if (irqtp->flags) - set_bits(irqtp->flags, &curtp->flags); - } else -#endif - __do_IRQ(irq, regs); + if (irq < NR_IRQS) { + spin_lock(&pending_irqs_lock); + pending_irqs[irq]++; + num_pending_irqs++; + spin_unlock(&pending_irqs_lock); + } else { + printk(KERN_WARNING "int_received: bad irq number %d\n", + irq); + HvCallPci_eoi(event->data.slot.bus_number, + event->data.slot.sub_bus_number, + event->data.slot.dev_id); + } break; /* Ignore error recovery events for now */ case pe_bus_created: @@ -342,6 +340,8 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, int iSeries_get_irq(struct pt_regs *regs) { struct paca_struct *lpaca; + /* -2 means ignore this interrupt */ + int irq = -2; lpaca = get_paca(); #ifdef CONFIG_SMP @@ -353,6 +353,19 @@ int iSeries_get_irq(struct pt_regs *regs) if (hvlpevent_is_pending()) process_hvlpevents(regs); - /* -2 means ignore this interrupt */ - return -2; + if (num_pending_irqs) { + spin_lock(&pending_irqs_lock); + for (irq = 0; irq < NR_IRQS; irq++) { + if (pending_irqs[irq]) { + pending_irqs[irq]--; + num_pending_irqs--; + break; + } + } + spin_unlock(&pending_irqs_lock); + if (irq >= NR_IRQS) + irq = -2; + } + + return irq; } |