openpic: always call IRQ_check from IRQ_get_next

Previously the code relied on the queue's "next" field getting
set to -1 sometime between an update to the bitmap, and the next
call to IRQ_get_next.  Sometimes this happened after the update.
Sometimes it happened before the check.  Sometimes it didn't happen
at all.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Scott Wood 2012-12-21 16:15:46 +00:00 committed by Alexander Graf
parent 72c1da2ca7
commit 3c94378e2c

View File

@ -315,10 +315,8 @@ out:
static int IRQ_get_next(OpenPICState *opp, IRQQueue *q) static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)
{ {
if (q->next == -1) {
/* XXX: optimize */ /* XXX: optimize */
IRQ_check(opp, q); IRQ_check(opp, q);
}
return q->next; return q->next;
} }
@ -365,7 +363,7 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ)
__func__, n_IRQ, dst->raised.next, n_CPU); __func__, n_IRQ, dst->raised.next, n_CPU);
return; return;
} }
IRQ_get_next(opp, &dst->raised); IRQ_check(opp, &dst->raised);
if (IRQ_get_next(opp, &dst->servicing) != -1 && if (IRQ_get_next(opp, &dst->servicing) != -1 &&
priority <= dst->servicing.priority) { priority <= dst->servicing.priority) {
DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n", DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
@ -916,7 +914,6 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
DPRINTF("EOI\n"); DPRINTF("EOI\n");
s_IRQ = IRQ_get_next(opp, &dst->servicing); s_IRQ = IRQ_get_next(opp, &dst->servicing);
IRQ_resetbit(&dst->servicing, s_IRQ); IRQ_resetbit(&dst->servicing, s_IRQ);
dst->servicing.next = -1;
/* Set up next servicing IRQ */ /* Set up next servicing IRQ */
s_IRQ = IRQ_get_next(opp, &dst->servicing); s_IRQ = IRQ_get_next(opp, &dst->servicing);
/* Check queued interrupts. */ /* Check queued interrupts. */
@ -993,7 +990,6 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
retval = IVPR_VECTOR(opp, src->ivpr); retval = IVPR_VECTOR(opp, src->ivpr);
} }
IRQ_resetbit(&dst->raised, n_IRQ); IRQ_resetbit(&dst->raised, n_IRQ);
dst->raised.next = -1;
if (!(src->ivpr & IVPR_SENSE_MASK)) { if (!(src->ivpr & IVPR_SENSE_MASK)) {
/* edge-sensitive IRQ */ /* edge-sensitive IRQ */
src->ivpr &= ~IVPR_ACTIVITY_MASK; src->ivpr &= ~IVPR_ACTIVITY_MASK;