aboutsummaryrefslogtreecommitdiff
path: root/hw/openpic.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2012-12-21 16:15:46 +0000
committerAlexander Graf <agraf@suse.de>2013-01-07 17:37:10 +0100
commit3c94378e2c500b6211e95d7457f4a9959955c3d1 (patch)
treeff25ac6ecc0c9e3771b06f60e4d1a8fca5dd73c3 /hw/openpic.c
parent72c1da2ca72af50e6536d0cd9c6db758f66cd7c2 (diff)
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>
Diffstat (limited to 'hw/openpic.c')
-rw-r--r--hw/openpic.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/hw/openpic.c b/hw/openpic.c
index ac5027a5a0..19e6280023 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -315,10 +315,8 @@ out:
static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)
{
- if (q->next == -1) {
- /* XXX: optimize */
- IRQ_check(opp, q);
- }
+ /* XXX: optimize */
+ IRQ_check(opp, q);
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);
return;
}
- IRQ_get_next(opp, &dst->raised);
+ IRQ_check(opp, &dst->raised);
if (IRQ_get_next(opp, &dst->servicing) != -1 &&
priority <= dst->servicing.priority) {
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");
s_IRQ = IRQ_get_next(opp, &dst->servicing);
IRQ_resetbit(&dst->servicing, s_IRQ);
- dst->servicing.next = -1;
/* Set up next servicing IRQ */
s_IRQ = IRQ_get_next(opp, &dst->servicing);
/* Check queued interrupts. */
@@ -993,7 +990,6 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
retval = IVPR_VECTOR(opp, src->ivpr);
}
IRQ_resetbit(&dst->raised, n_IRQ);
- dst->raised.next = -1;
if (!(src->ivpr & IVPR_SENSE_MASK)) {
/* edge-sensitive IRQ */
src->ivpr &= ~IVPR_ACTIVITY_MASK;