summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/irq.h6
-rw-r--r--kernel/irq/migration.c28
2 files changed, 27 insertions, 7 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 3eab46f590a9..a31a7d8acdb2 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -205,6 +205,7 @@ static inline void set_native_irq_info(int irq, cpumask_t mask)
void set_pending_irq(unsigned int irq, cpumask_t mask);
void move_native_irq(int irq);
+void move_masked_irq(int irq);
#ifdef CONFIG_PCI_MSI
/*
@@ -246,6 +247,10 @@ static inline void move_native_irq(int irq)
{
}
+static inline void move_masked_irq(int irq)
+{
+}
+
static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
{
}
@@ -261,6 +266,7 @@ static inline void set_irq_info(int irq, cpumask_t mask)
#define move_irq(x)
#define move_native_irq(x)
+#define move_masked_irq(x)
#endif /* CONFIG_SMP */
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 9b234df810d0..4baa3bbcd25a 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -12,7 +12,7 @@ void set_pending_irq(unsigned int irq, cpumask_t mask)
spin_unlock_irqrestore(&desc->lock, flags);
}
-void move_native_irq(int irq)
+void move_masked_irq(int irq)
{
struct irq_desc *desc = irq_desc + irq;
cpumask_t tmp;
@@ -48,15 +48,29 @@ void move_native_irq(int irq)
* when an active trigger is comming in. This could
* cause some ioapics to mal-function.
* Being paranoid i guess!
+ *
+ * For correct operation this depends on the caller
+ * masking the irqs.
*/
if (likely(!cpus_empty(tmp))) {
- if (likely(!(desc->status & IRQ_DISABLED)))
- desc->chip->disable(irq);
-
desc->chip->set_affinity(irq,tmp);
-
- if (likely(!(desc->status & IRQ_DISABLED)))
- desc->chip->enable(irq);
}
cpus_clear(irq_desc[irq].pending_mask);
}
+
+void move_native_irq(int irq)
+{
+ struct irq_desc *desc = irq_desc + irq;
+
+ if (likely(!(desc->status & IRQ_MOVE_PENDING)))
+ return;
+
+ if (likely(!(desc->status & IRQ_DISABLED)))
+ desc->chip->disable(irq);
+
+ move_masked_irq(irq);
+
+ if (likely(!(desc->status & IRQ_DISABLED)))
+ desc->chip->enable(irq);
+}
+