Commit fa27271b authored by Thomas Gleixner's avatar Thomas Gleixner

genirq: Fixup poll handling

try_one_irq() contains redundant code and lots of useless checks for
shared interrupts. Check for shared before setting IRQ_INPROGRESS and
then call handle_IRQ_event() while pending. Shorter version with the
same functionality.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent b738a50a
...@@ -42,48 +42,36 @@ static int try_one_irq(int irq, struct irq_desc *desc) ...@@ -42,48 +42,36 @@ static int try_one_irq(int irq, struct irq_desc *desc)
raw_spin_unlock(&desc->lock); raw_spin_unlock(&desc->lock);
return ok; return ok;
} }
/* Honour the normal IRQ locking */
desc->status |= IRQ_INPROGRESS;
action = desc->action;
raw_spin_unlock(&desc->lock);
while (action) {
/* Only shared IRQ handlers are safe to call */
if (action->flags & IRQF_SHARED) {
if (action->handler(irq, action->dev_id) ==
IRQ_HANDLED)
ok = 1;
}
action = action->next;
}
local_irq_disable();
/* Now clean up the flags */
raw_spin_lock(&desc->lock);
action = desc->action;
/* /*
* While we were looking for a fixup someone queued a real * All handlers must agree on IRQF_SHARED, so we test just the
* IRQ clashing with our walk: * first. Check for action->next as well.
*/ */
while ((desc->status & IRQ_PENDING) && action) { action = desc->action;
/* if (!action || !(action->flags & IRQF_SHARED) || !action->next)
* Perform real IRQ processing for the IRQ we deferred goto out;
*/
work = 1; /* Honour the normal IRQ locking */
desc->status |= IRQ_INPROGRESS;
do {
work++;
desc->status &= ~IRQ_PENDING;
raw_spin_unlock(&desc->lock); raw_spin_unlock(&desc->lock);
handle_IRQ_event(irq, action); if (handle_IRQ_event(irq, action) != IRQ_NONE)
ok = 1;
raw_spin_lock(&desc->lock); raw_spin_lock(&desc->lock);
desc->status &= ~IRQ_PENDING; action = desc->action;
} } while ((desc->status & IRQ_PENDING) && action);
desc->status &= ~IRQ_INPROGRESS; desc->status &= ~IRQ_INPROGRESS;
/* /*
* If we did actual work for the real IRQ line we must let the * If we did actual work for the real IRQ line we must let the
* IRQ controller clean up too * IRQ controller clean up too
*/ */
if (work) if (work > 1)
irq_end(irq, desc); irq_end(irq, desc);
raw_spin_unlock(&desc->lock);
out:
raw_spin_unlock(&desc->lock);
return ok; return ok;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment