Commit 1d7a6b97 authored by Stephen Rothwell's avatar Stephen Rothwell Committed by Paul Mackerras

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: default avatarStephen Rothwell <sfr@canb.auug.org.au>
parent a50b56d2
...@@ -82,31 +82,29 @@ struct pci_event { ...@@ -82,31 +82,29 @@ struct pci_event {
} data; } 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) static void int_received(struct pci_event *event, struct pt_regs *regs)
{ {
int irq; int irq;
#ifdef CONFIG_IRQSTACKS
struct thread_info *curtp, *irqtp;
#endif
switch (event->event.xSubtype) { switch (event->event.xSubtype) {
case pe_slot_interrupt: case pe_slot_interrupt:
irq = event->event.xCorrelationToken; irq = event->event.xCorrelationToken;
/* Dispatch the interrupt handlers for this irq */ if (irq < NR_IRQS) {
#ifdef CONFIG_IRQSTACKS spin_lock(&pending_irqs_lock);
/* Switch to the irq stack to handle this */ pending_irqs[irq]++;
curtp = current_thread_info(); num_pending_irqs++;
irqtp = hardirq_ctx[smp_processor_id()]; spin_unlock(&pending_irqs_lock);
if (curtp != irqtp) { } else {
irqtp->task = curtp->task; printk(KERN_WARNING "int_received: bad irq number %d\n",
irqtp->flags = 0; irq);
call___do_IRQ(irq, regs, irqtp); HvCallPci_eoi(event->data.slot.bus_number,
irqtp->task = NULL; event->data.slot.sub_bus_number,
if (irqtp->flags) event->data.slot.dev_id);
set_bits(irqtp->flags, &curtp->flags); }
} else
#endif
__do_IRQ(irq, regs);
break; break;
/* Ignore error recovery events for now */ /* Ignore error recovery events for now */
case pe_bus_created: case pe_bus_created:
...@@ -342,6 +340,8 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, ...@@ -342,6 +340,8 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
int iSeries_get_irq(struct pt_regs *regs) int iSeries_get_irq(struct pt_regs *regs)
{ {
struct paca_struct *lpaca; struct paca_struct *lpaca;
/* -2 means ignore this interrupt */
int irq = -2;
lpaca = get_paca(); lpaca = get_paca();
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -353,6 +353,19 @@ int iSeries_get_irq(struct pt_regs *regs) ...@@ -353,6 +353,19 @@ int iSeries_get_irq(struct pt_regs *regs)
if (hvlpevent_is_pending()) if (hvlpevent_is_pending())
process_hvlpevents(regs); process_hvlpevents(regs);
/* -2 means ignore this interrupt */ if (num_pending_irqs) {
return -2; 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;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment