} 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:
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
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;
}