From 1d7a6b97f3c30087e307655116ff2ed492a37ad0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 17 Nov 2005 18:04:37 +1100 Subject: 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 --- arch/powerpc/platforms/iseries/irq.c | 53 ++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'arch/powerpc/platforms') diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 5e92149b9b9..42e978e4897 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; } -- cgit v1.2.3