genirq: threaded irq handlers review fixups
authorThomas Gleixner <tglx@linutronix.de>
Tue, 24 Mar 2009 10:46:22 +0000 (11:46 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 24 Mar 2009 11:15:23 +0000 (12:15 +0100)
Delta patch to address the review comments.

      - Implement warning when IRQ_WAKE_THREAD is requested and no
        thread handler installed
      - coding style fixes

Pointed-out-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/interrupt.h
kernel/irq/handle.c
kernel/irq/manage.c

index dbf6a6f..266a5f5 100644 (file)
  * Bits used by threaded handlers:
  * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run
  * IRQTF_DIED      - handler thread died
+ * IRQTF_WARNED    - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed
  */
 enum {
        IRQTF_RUNTHREAD,
        IRQTF_DIED,
+       IRQTF_WARNED,
 };
 
 typedef irqreturn_t (*irq_handler_t)(int, void *);
index fe8f453..38b49a9 100644 (file)
@@ -338,6 +338,15 @@ irqreturn_t no_action(int cpl, void *dev_id)
        return IRQ_NONE;
 }
 
+static void warn_no_thread(unsigned int irq, struct irqaction *action)
+{
+       if (test_and_set_bit(IRQTF_WARNED, &action->thread_flags))
+               return;
+
+       printk(KERN_WARNING "IRQ %d device %s returned IRQ_WAKE_THREAD "
+              "but no thread function available.", irq, action->name);
+}
+
 /**
  * handle_IRQ_event - irq action chain handler
  * @irq:       the interrupt number
@@ -361,6 +370,21 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
                switch (ret) {
                case IRQ_WAKE_THREAD:
                        /*
+                        * Set result to handled so the spurious check
+                        * does not trigger.
+                        */
+                       ret = IRQ_HANDLED;
+
+                       /*
+                        * Catch drivers which return WAKE_THREAD but
+                        * did not set up a thread function
+                        */
+                       if (unlikely(!action->thread_fn)) {
+                               warn_no_thread(irq, action);
+                               break;
+                       }
+
+                       /*
                         * Wake up the handler thread for this
                         * action. In case the thread crashed and was
                         * killed we just pretend that we handled the
@@ -374,11 +398,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
                                wake_up_process(action->thread);
                        }
 
-                       /*
-                        * Set it to handled so the spurious check
-                        * does not trigger.
-                        */
-                       ret = IRQ_HANDLED;
                        /* Fall through to add to randomness */
                case IRQ_HANDLED:
                        status |= action->flags;
index a4c1ab8..a3eb7ba 100644 (file)
@@ -407,20 +407,17 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
        return ret;
 }
 
-static inline int irq_thread_should_run(struct irqaction *action)
-{
-       return test_and_clear_bit(IRQTF_RUNTHREAD, &action->thread_flags);
-}
-
 static int irq_wait_for_interrupt(struct irqaction *action)
 {
        while (!kthread_should_stop()) {
                set_current_state(TASK_INTERRUPTIBLE);
-               if (irq_thread_should_run(action)) {
+
+               if (test_and_clear_bit(IRQTF_RUNTHREAD,
+                                      &action->thread_flags)) {
                        __set_current_state(TASK_RUNNING);
                        return 0;
-               } else
-                       schedule();
+               }
+               schedule();
        }
        return -1;
 }
@@ -820,8 +817,8 @@ EXPORT_SYMBOL(free_irq);
  *     @irq: Interrupt line to allocate
  *     @handler: Function to be called when the IRQ occurs.
  *               Primary handler for threaded interrupts
- *      @thread_fn: Function called from the irq handler thread
- *                  If NULL, no irq thread is created
+ *     @thread_fn: Function called from the irq handler thread
+ *                 If NULL, no irq thread is created
  *     @irqflags: Interrupt type flags
  *     @devname: An ascii name for the claiming device
  *     @dev_id: A cookie passed back to the handler function