aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2009-03-24 06:46:22 -0400
committerThomas Gleixner <tglx@linutronix.de>2009-03-24 07:15:23 -0400
commitf48fe81e5b032914183e9a17052313720c2cac56 (patch)
tree9404047368387a6f8b39b4a822ef28e18eba45e9
parent935bd5b971f0df7c06d214d022cf8392e2f37952 (diff)
genirq: threaded irq handlers review fixups
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>
-rw-r--r--include/linux/interrupt.h2
-rw-r--r--kernel/irq/handle.c29
-rw-r--r--kernel/irq/manage.c17
3 files changed, 33 insertions, 15 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index dbf6a6fd116c..266a5f5f57cc 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -63,10 +63,12 @@
63 * Bits used by threaded handlers: 63 * Bits used by threaded handlers:
64 * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run 64 * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run
65 * IRQTF_DIED - handler thread died 65 * IRQTF_DIED - handler thread died
66 * IRQTF_WARNED - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed
66 */ 67 */
67enum { 68enum {
68 IRQTF_RUNTHREAD, 69 IRQTF_RUNTHREAD,
69 IRQTF_DIED, 70 IRQTF_DIED,
71 IRQTF_WARNED,
70}; 72};
71 73
72typedef irqreturn_t (*irq_handler_t)(int, void *); 74typedef irqreturn_t (*irq_handler_t)(int, void *);
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index fe8f45374e86..38b49a9e508a 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -338,6 +338,15 @@ irqreturn_t no_action(int cpl, void *dev_id)
338 return IRQ_NONE; 338 return IRQ_NONE;
339} 339}
340 340
341static void warn_no_thread(unsigned int irq, struct irqaction *action)
342{
343 if (test_and_set_bit(IRQTF_WARNED, &action->thread_flags))
344 return;
345
346 printk(KERN_WARNING "IRQ %d device %s returned IRQ_WAKE_THREAD "
347 "but no thread function available.", irq, action->name);
348}
349
341/** 350/**
342 * handle_IRQ_event - irq action chain handler 351 * handle_IRQ_event - irq action chain handler
343 * @irq: the interrupt number 352 * @irq: the interrupt number
@@ -361,6 +370,21 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
361 switch (ret) { 370 switch (ret) {
362 case IRQ_WAKE_THREAD: 371 case IRQ_WAKE_THREAD:
363 /* 372 /*
373 * Set result to handled so the spurious check
374 * does not trigger.
375 */
376 ret = IRQ_HANDLED;
377
378 /*
379 * Catch drivers which return WAKE_THREAD but
380 * did not set up a thread function
381 */
382 if (unlikely(!action->thread_fn)) {
383 warn_no_thread(irq, action);
384 break;
385 }
386
387 /*
364 * Wake up the handler thread for this 388 * Wake up the handler thread for this
365 * action. In case the thread crashed and was 389 * action. In case the thread crashed and was
366 * killed we just pretend that we handled the 390 * killed we just pretend that we handled the
@@ -374,11 +398,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
374 wake_up_process(action->thread); 398 wake_up_process(action->thread);
375 } 399 }
376 400
377 /*
378 * Set it to handled so the spurious check
379 * does not trigger.
380 */
381 ret = IRQ_HANDLED;
382 /* Fall through to add to randomness */ 401 /* Fall through to add to randomness */
383 case IRQ_HANDLED: 402 case IRQ_HANDLED:
384 status |= action->flags; 403 status |= action->flags;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a4c1ab86cd25..a3eb7baf1e46 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -407,20 +407,17 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
407 return ret; 407 return ret;
408} 408}
409 409
410static inline int irq_thread_should_run(struct irqaction *action)
411{
412 return test_and_clear_bit(IRQTF_RUNTHREAD, &action->thread_flags);
413}
414
415static int irq_wait_for_interrupt(struct irqaction *action) 410static int irq_wait_for_interrupt(struct irqaction *action)
416{ 411{
417 while (!kthread_should_stop()) { 412 while (!kthread_should_stop()) {
418 set_current_state(TASK_INTERRUPTIBLE); 413 set_current_state(TASK_INTERRUPTIBLE);
419 if (irq_thread_should_run(action)) { 414
415 if (test_and_clear_bit(IRQTF_RUNTHREAD,
416 &action->thread_flags)) {
420 __set_current_state(TASK_RUNNING); 417 __set_current_state(TASK_RUNNING);
421 return 0; 418 return 0;
422 } else 419 }
423 schedule(); 420 schedule();
424 } 421 }
425 return -1; 422 return -1;
426} 423}
@@ -820,8 +817,8 @@ EXPORT_SYMBOL(free_irq);
820 * @irq: Interrupt line to allocate 817 * @irq: Interrupt line to allocate
821 * @handler: Function to be called when the IRQ occurs. 818 * @handler: Function to be called when the IRQ occurs.
822 * Primary handler for threaded interrupts 819 * Primary handler for threaded interrupts
823 * @thread_fn: Function called from the irq handler thread 820 * @thread_fn: Function called from the irq handler thread
824 * If NULL, no irq thread is created 821 * If NULL, no irq thread is created
825 * @irqflags: Interrupt type flags 822 * @irqflags: Interrupt type flags
826 * @devname: An ascii name for the claiming device 823 * @devname: An ascii name for the claiming device
827 * @dev_id: A cookie passed back to the handler function 824 * @dev_id: A cookie passed back to the handler function