Skip to content

Commit

Permalink
allwinner-a10-pit: avoid generation of spurious interrupts
Browse files Browse the repository at this point in the history
The model was generating interrupts for all enabled timers after the
expiration of one of them. Avoid this by passing explicitly the timer
index to the callback function.

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Reviewed-by: Li Guang <lig.fnst@cn.fujitsu.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 1395771730-16882-4-git-send-email-b.galvani@gmail.com
[PMM: avoid duplicate typedef of AwA10PITState]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
bengal authored and pm215 committed Apr 17, 2014
1 parent 2237094 commit 323a877
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
25 changes: 14 additions & 11 deletions hw/timer/allwinner-a10-pit.c
Expand Up @@ -193,18 +193,17 @@ static void a10_pit_reset(DeviceState *dev)

static void a10_pit_timer_cb(void *opaque)
{
AwA10PITState *s = AW_A10_PIT(opaque);
uint8_t i;
AwA10TimerContext *tc = opaque;
AwA10PITState *s = tc->container;
uint8_t i = tc->index;

for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
if (s->control[i] & AW_A10_PIT_TIMER_EN) {
s->irq_status |= 1 << i;
if (s->control[i] & AW_A10_PIT_TIMER_MODE) {
ptimer_stop(s->timer[i]);
s->control[i] &= ~AW_A10_PIT_TIMER_EN;
}
qemu_irq_pulse(s->irq[i]);
if (s->control[i] & AW_A10_PIT_TIMER_EN) {
s->irq_status |= 1 << i;
if (s->control[i] & AW_A10_PIT_TIMER_MODE) {
ptimer_stop(s->timer[i]);
s->control[i] &= ~AW_A10_PIT_TIMER_EN;
}
qemu_irq_pulse(s->irq[i]);
}
}

Expand All @@ -223,7 +222,11 @@ static void a10_pit_init(Object *obj)
sysbus_init_mmio(sbd, &s->iomem);

for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
bh[i] = qemu_bh_new(a10_pit_timer_cb, s);
AwA10TimerContext *tc = &s->timer_context[i];

tc->container = s;
tc->index = i;
bh[i] = qemu_bh_new(a10_pit_timer_cb, tc);
s->timer[i] = ptimer_init(bh[i]);
ptimer_set_freq(s->timer[i], 240000);
}
Expand Down
12 changes: 10 additions & 2 deletions include/hw/timer/allwinner-a10-pit.h
Expand Up @@ -35,12 +35,20 @@

#define AW_A10_PIT_DEFAULT_CLOCK 0x4

typedef struct AwA10PITState {
typedef struct AwA10PITState AwA10PITState;

typedef struct AwA10TimerContext {
AwA10PITState *container;
int index;
} AwA10TimerContext;

struct AwA10PITState {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
qemu_irq irq[AW_A10_PIT_TIMER_NR];
ptimer_state * timer[AW_A10_PIT_TIMER_NR];
AwA10TimerContext timer_context[AW_A10_PIT_TIMER_NR];
MemoryRegion iomem;

uint32_t irq_enable;
Expand All @@ -53,6 +61,6 @@ typedef struct AwA10PITState {
uint32_t count_lo;
uint32_t count_hi;
uint32_t count_ctl;
} AwA10PITState;
};

#endif

0 comments on commit 323a877

Please sign in to comment.