diff options
Diffstat (limited to 'kernel/time/tick-broadcast.c')
| -rw-r--r-- | kernel/time/tick-broadcast.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 8001d37071f5..db8e0f3d409b 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
| @@ -31,6 +31,12 @@ struct tick_device tick_broadcast_device; | |||
| 31 | static cpumask_t tick_broadcast_mask; | 31 | static cpumask_t tick_broadcast_mask; |
| 32 | static DEFINE_SPINLOCK(tick_broadcast_lock); | 32 | static DEFINE_SPINLOCK(tick_broadcast_lock); |
| 33 | 33 | ||
| 34 | #ifdef CONFIG_TICK_ONESHOT | ||
| 35 | static void tick_broadcast_clear_oneshot(int cpu); | ||
| 36 | #else | ||
| 37 | static inline void tick_broadcast_clear_oneshot(int cpu) { } | ||
| 38 | #endif | ||
| 39 | |||
| 34 | /* | 40 | /* |
| 35 | * Debugging: see timer_list.c | 41 | * Debugging: see timer_list.c |
| 36 | */ | 42 | */ |
| @@ -49,7 +55,7 @@ cpumask_t *tick_get_broadcast_mask(void) | |||
| 49 | */ | 55 | */ |
| 50 | static void tick_broadcast_start_periodic(struct clock_event_device *bc) | 56 | static void tick_broadcast_start_periodic(struct clock_event_device *bc) |
| 51 | { | 57 | { |
| 52 | if (bc && bc->mode == CLOCK_EVT_MODE_SHUTDOWN) | 58 | if (bc) |
| 53 | tick_setup_periodic(bc, 1); | 59 | tick_setup_periodic(bc, 1); |
| 54 | } | 60 | } |
| 55 | 61 | ||
| @@ -99,8 +105,19 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) | |||
| 99 | cpu_set(cpu, tick_broadcast_mask); | 105 | cpu_set(cpu, tick_broadcast_mask); |
| 100 | tick_broadcast_start_periodic(tick_broadcast_device.evtdev); | 106 | tick_broadcast_start_periodic(tick_broadcast_device.evtdev); |
| 101 | ret = 1; | 107 | ret = 1; |
| 102 | } | 108 | } else { |
| 109 | /* | ||
| 110 | * When the new device is not affected by the stop | ||
| 111 | * feature and the cpu is marked in the broadcast mask | ||
| 112 | * then clear the broadcast bit. | ||
| 113 | */ | ||
| 114 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) { | ||
| 115 | int cpu = smp_processor_id(); | ||
| 103 | 116 | ||
| 117 | cpu_clear(cpu, tick_broadcast_mask); | ||
| 118 | tick_broadcast_clear_oneshot(cpu); | ||
| 119 | } | ||
| 120 | } | ||
| 104 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 121 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
| 105 | return ret; | 122 | return ret; |
| 106 | } | 123 | } |
| @@ -299,7 +316,7 @@ void tick_suspend_broadcast(void) | |||
| 299 | spin_lock_irqsave(&tick_broadcast_lock, flags); | 316 | spin_lock_irqsave(&tick_broadcast_lock, flags); |
| 300 | 317 | ||
| 301 | bc = tick_broadcast_device.evtdev; | 318 | bc = tick_broadcast_device.evtdev; |
| 302 | if (bc && tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) | 319 | if (bc) |
| 303 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); | 320 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); |
| 304 | 321 | ||
| 305 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 322 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
| @@ -316,6 +333,8 @@ int tick_resume_broadcast(void) | |||
| 316 | bc = tick_broadcast_device.evtdev; | 333 | bc = tick_broadcast_device.evtdev; |
| 317 | 334 | ||
| 318 | if (bc) { | 335 | if (bc) { |
| 336 | clockevents_set_mode(bc, CLOCK_EVT_MODE_RESUME); | ||
| 337 | |||
| 319 | switch (tick_broadcast_device.mode) { | 338 | switch (tick_broadcast_device.mode) { |
| 320 | case TICKDEV_MODE_PERIODIC: | 339 | case TICKDEV_MODE_PERIODIC: |
| 321 | if(!cpus_empty(tick_broadcast_mask)) | 340 | if(!cpus_empty(tick_broadcast_mask)) |
| @@ -485,6 +504,16 @@ out: | |||
| 485 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 504 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
| 486 | } | 505 | } |
| 487 | 506 | ||
| 507 | /* | ||
| 508 | * Reset the one shot broadcast for a cpu | ||
| 509 | * | ||
| 510 | * Called with tick_broadcast_lock held | ||
| 511 | */ | ||
| 512 | static void tick_broadcast_clear_oneshot(int cpu) | ||
| 513 | { | ||
| 514 | cpu_clear(cpu, tick_broadcast_oneshot_mask); | ||
| 515 | } | ||
| 516 | |||
| 488 | /** | 517 | /** |
| 489 | * tick_broadcast_setup_highres - setup the broadcast device for highres | 518 | * tick_broadcast_setup_highres - setup the broadcast device for highres |
| 490 | */ | 519 | */ |
