Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 234703
b: refs/heads/master
c: c7259cd
h: refs/heads/master
i:
  234701: ab7e40c
  234699: b97a691
  234695: 251c15b
  234687: 6c9ff4c
v: v3
  • Loading branch information
Thomas Gleixner committed Feb 19, 2011
1 parent cc28cd5 commit 5e6c294
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fa27271bc8d230355c1f24ddea103824fdc12de6
refs/heads/master: c7259cd7af757ddcd65701c37099dcddae2054f0
40 changes: 26 additions & 14 deletions trunk/kernel/irq/spurious.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,42 @@ static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0);
/*
* Recovery handler for misrouted interrupts.
*/
static int try_one_irq(int irq, struct irq_desc *desc)
static int try_one_irq(int irq, struct irq_desc *desc, bool force)
{
struct irqaction *action;
int ok = 0, work = 0;

raw_spin_lock(&desc->lock);

/* PER_CPU and nested thread interrupts are never polled */
if (desc->status & (IRQ_PER_CPU | IRQ_NESTED_THREAD))
goto out;

/*
* Do not poll disabled interrupts unless the spurious
* disabled poller asks explicitely.
*/
if ((desc->status & IRQ_DISABLED) && !force)
goto out;

/*
* 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->flags & __IRQF_TIMER) || !action->next)
goto out;

/* Already running on another processor */
if (desc->status & IRQ_INPROGRESS) {
/*
* Already running: If it is shared get the other
* CPU to go looking for our mystery interrupt too
*/
if (desc->action && (desc->action->flags & IRQF_SHARED))
desc->status |= IRQ_PENDING;
raw_spin_unlock(&desc->lock);
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)
desc->status |= IRQ_PENDING;
goto out;
}

/* Honour the normal IRQ locking */
desc->status |= IRQ_INPROGRESS;
Expand Down Expand Up @@ -87,7 +99,7 @@ static int misrouted_irq(int irq)
if (i == irq) /* Already tried */
continue;

if (try_one_irq(i, desc))
if (try_one_irq(i, desc, false))
ok = 1;
}
/* So the caller can adjust the irq error counts */
Expand All @@ -112,7 +124,7 @@ static void poll_spurious_irqs(unsigned long dummy)
continue;

local_irq_disable();
try_one_irq(i, desc);
try_one_irq(i, desc, true);
local_irq_enable();
}

Expand Down

0 comments on commit 5e6c294

Please sign in to comment.