On 2 July 2015 at 18:20, Dmitry Osipenko <dig...@gmail.com> wrote: > Timer, running in periodic mode, can't be stopped or coming one-shot tick > won't be canceled because timer control code just doesn't handle timer > disabling. Fix it by deleting timer if enable bit isn't set. > > Signed-off-by: Dmitry Osipenko <dig...@gmail.com> > --- > > v2: Avoid calling timer_del() if the timer was already disabled as per > Peter Maydell suggestion. > > hw/timer/arm_mptimer.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c > index 8b93b3c..51c18de 100644 > --- a/hw/timer/arm_mptimer.c > +++ b/hw/timer/arm_mptimer.c > @@ -122,11 +122,17 @@ static void timerblock_write(void *opaque, hwaddr addr, > case 8: /* Control. */ > old = tb->control; > tb->control = value; > - if (((old & 1) == 0) && (value & 1)) { > + if (((old & 1) == 0) && ((value & 1) == 0)) { > + break; > + } > + if (value & 1) { > if (tb->count == 0 && (tb->control & 2)) { > tb->count = tb->load; > } > timerblock_reload(tb, 1); > + } else { > + /* Shutdown timer. */ > + timer_del(tb->timer);
This will now cause us to do the "reload the timer" logic if you write a 1 to the control bit when it was already 1, which we didn't do before. The logic I suggested in my previous review comment gets this right... -- PMM