Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f48fe81e authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

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: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 935bd5b9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -63,10 +63,12 @@
 * 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 *);
+24 −5
Original line number Diff line number Diff line
@@ -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
@@ -360,6 +369,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
@@ -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;
+7 −10
Original line number Diff line number Diff line
@@ -407,19 +407,16 @@ 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();
	}
	return -1;