|
@@ -32,24 +32,10 @@ static int __init setup_forced_irqthreads(char *arg)
|
|
|
early_param("threadirqs", setup_forced_irqthreads);
|
|
|
#endif
|
|
|
|
|
|
-/**
|
|
|
- * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
|
|
|
- * @irq: interrupt number to wait for
|
|
|
- *
|
|
|
- * This function waits for any pending IRQ handlers for this interrupt
|
|
|
- * to complete before returning. If you use this function while
|
|
|
- * holding a resource the IRQ handler may need you will deadlock.
|
|
|
- *
|
|
|
- * This function may be called - with care - from IRQ context.
|
|
|
- */
|
|
|
-void synchronize_irq(unsigned int irq)
|
|
|
+static void __synchronize_hardirq(struct irq_desc *desc)
|
|
|
{
|
|
|
- struct irq_desc *desc = irq_to_desc(irq);
|
|
|
bool inprogress;
|
|
|
|
|
|
- if (!desc)
|
|
|
- return;
|
|
|
-
|
|
|
do {
|
|
|
unsigned long flags;
|
|
|
|
|
@@ -67,12 +53,56 @@ void synchronize_irq(unsigned int irq)
|
|
|
|
|
|
/* Oops, that failed? */
|
|
|
} while (inprogress);
|
|
|
+}
|
|
|
|
|
|
- /*
|
|
|
- * We made sure that no hardirq handler is running. Now verify
|
|
|
- * that no threaded handlers are active.
|
|
|
- */
|
|
|
- wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
|
|
|
+/**
|
|
|
+ * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
|
|
|
+ * @irq: interrupt number to wait for
|
|
|
+ *
|
|
|
+ * This function waits for any pending hard IRQ handlers for this
|
|
|
+ * interrupt to complete before returning. If you use this
|
|
|
+ * function while holding a resource the IRQ handler may need you
|
|
|
+ * will deadlock. It does not take associated threaded handlers
|
|
|
+ * into account.
|
|
|
+ *
|
|
|
+ * Do not use this for shutdown scenarios where you must be sure
|
|
|
+ * that all parts (hardirq and threaded handler) have completed.
|
|
|
+ *
|
|
|
+ * This function may be called - with care - from IRQ context.
|
|
|
+ */
|
|
|
+void synchronize_hardirq(unsigned int irq)
|
|
|
+{
|
|
|
+ struct irq_desc *desc = irq_to_desc(irq);
|
|
|
+
|
|
|
+ if (desc)
|
|
|
+ __synchronize_hardirq(desc);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(synchronize_hardirq);
|
|
|
+
|
|
|
+/**
|
|
|
+ * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
|
|
|
+ * @irq: interrupt number to wait for
|
|
|
+ *
|
|
|
+ * This function waits for any pending IRQ handlers for this interrupt
|
|
|
+ * to complete before returning. If you use this function while
|
|
|
+ * holding a resource the IRQ handler may need you will deadlock.
|
|
|
+ *
|
|
|
+ * This function may be called - with care - from IRQ context.
|
|
|
+ */
|
|
|
+void synchronize_irq(unsigned int irq)
|
|
|
+{
|
|
|
+ struct irq_desc *desc = irq_to_desc(irq);
|
|
|
+
|
|
|
+ if (desc) {
|
|
|
+ __synchronize_hardirq(desc);
|
|
|
+ /*
|
|
|
+ * We made sure that no hardirq handler is
|
|
|
+ * running. Now verify that no threaded handlers are
|
|
|
+ * active.
|
|
|
+ */
|
|
|
+ wait_event(desc->wait_for_threads,
|
|
|
+ !atomic_read(&desc->threads_active));
|
|
|
+ }
|
|
|
}
|
|
|
EXPORT_SYMBOL(synchronize_irq);
|
|
|
|