]> Git Repo - qemu.git/commitdiff
arm_mptimer: Fix timer shutdown and mode change
authorDmitry Osipenko <[email protected]>
Sun, 5 Jul 2015 22:47:47 +0000 (01:47 +0300)
committerPeter Maydell <[email protected]>
Mon, 6 Jul 2015 09:25:37 +0000 (10:25 +0100)
The running timer can't be stopped because timer control code just
doesn't handle disabling the timer. Fix it by deleting the timer if
the enable bit is cleared.

The timer won't start periodic ticking if a ONE-SHOT -> PERIODIC mode
change happens after a one-shot tick was completed. Fix it by
re-starting ticking if the timer isn't ticking right now.

To avoid code churning, these two fixes are squashed in one commit.

Signed-off-by: Dmitry Osipenko <[email protected]>
Reviewed-by: Peter Crosthwaite <[email protected]>
Signed-off-by: Peter Maydell <[email protected]>
hw/timer/arm_mptimer.c

index 8b93b3c1ae670359542fc3104b2ca0f886da3a0e..0e132b15b5ac5ce12c6106a5df97c0b9ce05ccfd 100644 (file)
@@ -122,11 +122,18 @@ static void timerblock_write(void *opaque, hwaddr addr,
     case 8: /* Control.  */
         old = tb->control;
         tb->control = value;
-        if (((old & 1) == 0) && (value & 1)) {
-            if (tb->count == 0 && (tb->control & 2)) {
+        if (value & 1) {
+            if ((old & 1) && (tb->count != 0)) {
+                /* Do nothing if timer is ticking right now.  */
+                break;
+            }
+            if (tb->control & 2) {
                 tb->count = tb->load;
             }
             timerblock_reload(tb, 1);
+        } else if (old & 1) {
+            /* Shutdown the timer.  */
+            timer_del(tb->timer);
         }
         break;
     case 12: /* Interrupt status.  */
This page took 0.022586 seconds and 4 git commands to generate.