diff options
| -rw-r--r-- | kernel/time/tick-broadcast.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 3044a88357fa..5744f40b2697 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
| @@ -210,7 +210,7 @@ static void tick_do_broadcast_on_off(void *why) | |||
| 210 | struct clock_event_device *bc, *dev; | 210 | struct clock_event_device *bc, *dev; |
| 211 | struct tick_device *td; | 211 | struct tick_device *td; |
| 212 | unsigned long flags, *reason = why; | 212 | unsigned long flags, *reason = why; |
| 213 | int cpu; | 213 | int cpu, bc_stopped; |
| 214 | 214 | ||
| 215 | spin_lock_irqsave(&tick_broadcast_lock, flags); | 215 | spin_lock_irqsave(&tick_broadcast_lock, flags); |
| 216 | 216 | ||
| @@ -228,6 +228,8 @@ static void tick_do_broadcast_on_off(void *why) | |||
| 228 | if (!tick_device_is_functional(dev)) | 228 | if (!tick_device_is_functional(dev)) |
| 229 | goto out; | 229 | goto out; |
| 230 | 230 | ||
| 231 | bc_stopped = cpus_empty(tick_broadcast_mask); | ||
| 232 | |||
| 231 | switch (*reason) { | 233 | switch (*reason) { |
| 232 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: | 234 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: |
| 233 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: | 235 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: |
| @@ -250,9 +252,10 @@ static void tick_do_broadcast_on_off(void *why) | |||
| 250 | break; | 252 | break; |
| 251 | } | 253 | } |
| 252 | 254 | ||
| 253 | if (cpus_empty(tick_broadcast_mask)) | 255 | if (cpus_empty(tick_broadcast_mask)) { |
| 254 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); | 256 | if (!bc_stopped) |
| 255 | else { | 257 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); |
| 258 | } else if (bc_stopped) { | ||
| 256 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) | 259 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) |
| 257 | tick_broadcast_start_periodic(bc); | 260 | tick_broadcast_start_periodic(bc); |
| 258 | else | 261 | else |
| @@ -501,9 +504,12 @@ static void tick_broadcast_clear_oneshot(int cpu) | |||
| 501 | */ | 504 | */ |
| 502 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | 505 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) |
| 503 | { | 506 | { |
| 504 | bc->event_handler = tick_handle_oneshot_broadcast; | 507 | /* Set it up only once ! */ |
| 505 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | 508 | if (bc->event_handler != tick_handle_oneshot_broadcast) { |
| 506 | bc->next_event.tv64 = KTIME_MAX; | 509 | bc->event_handler = tick_handle_oneshot_broadcast; |
| 510 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | ||
| 511 | bc->next_event.tv64 = KTIME_MAX; | ||
| 512 | } | ||
| 507 | } | 513 | } |
| 508 | 514 | ||
| 509 | /* | 515 | /* |
