ppc64: allow iSeries to use IRQSTACKS again
authorStephen Rothwell <sfr@canb.auug.org.au>
Wed, 9 Nov 2005 04:07:16 +0000 (15:07 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 9 Nov 2005 04:07:16 +0000 (15:07 +1100)
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
arch/powerpc/platforms/iseries/irq.c

index a06603d84a451147d0cd646c40d18d9ef172bc94..a0ff7d95fdf3aaabc10016d66f2aee02663c28e4 100644 (file)
@@ -103,6 +103,9 @@ static void intReceived(struct XmPciLpEvent *eventParm,
                struct pt_regs *regsParm)
 {
        int irq;
+#ifdef CONFIG_IRQSTACKS
+       struct thread_info *curtp, *irqtp;
+#endif
 
        ++Pci_Interrupt_Count;
 
@@ -110,7 +113,20 @@ static void intReceived(struct XmPciLpEvent *eventParm,
        case XmPciLpEvent_SlotInterrupt:
                irq = eventParm->hvLpEvent.xCorrelationToken;
                /* Dispatch the interrupt handlers for this irq */
-               ppc_irq_dispatch_handler(regsParm, 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_ppc_irq_dispatch_handler(regsParm, irq, irqtp);
+                       irqtp->task = NULL;
+                       if (irqtp->flags)
+                               set_bits(irqtp->flags, &curtp->flags);
+               } else
+#endif
+                       ppc_irq_dispatch_handler(regsParm, irq);
                HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
                        eventParm->eventData.slotInterrupt.subBusNumber,
                        eventParm->eventData.slotInterrupt.deviceId);