forked from luck/tmp_suning_uos_patched
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: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
b738a50a20
commit
fa27271bc8
|
@ -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;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* All handlers must agree on IRQF_SHARED, so we test just the
|
||||||
|
* first. Check for action->next as well.
|
||||||
|
*/
|
||||||
|
action = desc->action;
|
||||||
|
if (!action || !(action->flags & IRQF_SHARED) || !action->next)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* Honour the normal IRQ locking */
|
/* Honour the normal IRQ locking */
|
||||||
desc->status |= IRQ_INPROGRESS;
|
desc->status |= IRQ_INPROGRESS;
|
||||||
action = desc->action;
|
do {
|
||||||
raw_spin_unlock(&desc->lock);
|
work++;
|
||||||
|
|
||||||
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
|
|
||||||
* IRQ clashing with our walk:
|
|
||||||
*/
|
|
||||||
while ((desc->status & IRQ_PENDING) && action) {
|
|
||||||
/*
|
|
||||||
* Perform real IRQ processing for the IRQ we deferred
|
|
||||||
*/
|
|
||||||
work = 1;
|
|
||||||
raw_spin_unlock(&desc->lock);
|
|
||||||
handle_IRQ_event(irq, action);
|
|
||||||
raw_spin_lock(&desc->lock);
|
|
||||||
desc->status &= ~IRQ_PENDING;
|
desc->status &= ~IRQ_PENDING;
|
||||||
}
|
raw_spin_unlock(&desc->lock);
|
||||||
|
if (handle_IRQ_event(irq, action) != IRQ_NONE)
|
||||||
|
ok = 1;
|
||||||
|
raw_spin_lock(&desc->lock);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user