提交 f48fe81e 编写于 作者: T Thomas Gleixner

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: NChristoph Hellwig <hch@infradead.org>
Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
上级 935bd5b9
...@@ -63,10 +63,12 @@ ...@@ -63,10 +63,12 @@
* Bits used by threaded handlers: * Bits used by threaded handlers:
* IRQTF_RUNTHREAD - signals that the interrupt handler thread should run * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run
* IRQTF_DIED - handler thread died * IRQTF_DIED - handler thread died
* IRQTF_WARNED - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed
*/ */
enum { enum {
IRQTF_RUNTHREAD, IRQTF_RUNTHREAD,
IRQTF_DIED, IRQTF_DIED,
IRQTF_WARNED,
}; };
typedef irqreturn_t (*irq_handler_t)(int, void *); typedef irqreturn_t (*irq_handler_t)(int, void *);
......
...@@ -338,6 +338,15 @@ irqreturn_t no_action(int cpl, void *dev_id) ...@@ -338,6 +338,15 @@ irqreturn_t no_action(int cpl, void *dev_id)
return IRQ_NONE; 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 * handle_IRQ_event - irq action chain handler
* @irq: the interrupt number * @irq: the interrupt number
...@@ -360,6 +369,21 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) ...@@ -360,6 +369,21 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
switch (ret) { switch (ret) {
case IRQ_WAKE_THREAD: 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 * Wake up the handler thread for this
* action. In case the thread crashed and was * action. In case the thread crashed and was
...@@ -374,11 +398,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) ...@@ -374,11 +398,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
wake_up_process(action->thread); 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 */ /* Fall through to add to randomness */
case IRQ_HANDLED: case IRQ_HANDLED:
status |= action->flags; status |= action->flags;
......
...@@ -407,20 +407,17 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, ...@@ -407,20 +407,17 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
return ret; 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) static int irq_wait_for_interrupt(struct irqaction *action)
{ {
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE); 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); __set_current_state(TASK_RUNNING);
return 0; return 0;
} else }
schedule(); schedule();
} }
return -1; return -1;
} }
...@@ -820,8 +817,8 @@ EXPORT_SYMBOL(free_irq); ...@@ -820,8 +817,8 @@ EXPORT_SYMBOL(free_irq);
* @irq: Interrupt line to allocate * @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs. * @handler: Function to be called when the IRQ occurs.
* Primary handler for threaded interrupts * Primary handler for threaded interrupts
* @thread_fn: Function called from the irq handler thread * @thread_fn: Function called from the irq handler thread
* If NULL, no irq thread is created * If NULL, no irq thread is created
* @irqflags: Interrupt type flags * @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device * @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function * @dev_id: A cookie passed back to the handler function
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册