Merge to Fedora kernel-2.6.7-1.492
[linux-2.6.git] / arch / ia64 / sn / kernel / irq.c
index 88f0bba..b0f720e 100644 (file)
@@ -41,6 +41,7 @@ static void force_interrupt(int irq);
 extern void pcibr_force_interrupt(pcibr_intr_t intr);
 extern int sn_force_interrupt_flag;
 struct irq_desc * sn_irq_desc(unsigned int irq);
+extern cpumask_t    __cacheline_aligned pending_irq_cpumask[NR_IRQS];
 
 struct sn_intr_list_t {
        struct sn_intr_list_t *next;
@@ -71,6 +72,21 @@ sn_enable_irq(unsigned int irq)
 {
 }
 
+static inline void sn_move_irq(int irq)
+{
+       /* note - we hold desc->lock */
+       cpumask_t tmp;
+       irq_desc_t *desc = irq_descp(irq);
+
+       if (!cpus_empty(pending_irq_cpumask[irq])) {
+               cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map);
+               if (unlikely(!cpus_empty(tmp))) {
+                       desc->handler->set_affinity(irq, pending_irq_cpumask[irq]);
+               }
+               cpus_clear(pending_irq_cpumask[irq]);
+       }
+}
+
 static void
 sn_ack_irq(unsigned int irq)
 {
@@ -94,6 +110,7 @@ sn_ack_irq(unsigned int irq)
        }
        HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask );
        __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
+       sn_move_irq(irq);
 }
 
 static void