diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/time/tick-broadcast.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 8339af229cb9..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 | */ |
@@ -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 | } |
@@ -487,6 +504,16 @@ out: | |||
487 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 504 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
488 | } | 505 | } |
489 | 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 | |||
490 | /** | 517 | /** |
491 | * tick_broadcast_setup_highres - setup the broadcast device for highres | 518 | * tick_broadcast_setup_highres - setup the broadcast device for highres |
492 | */ | 519 | */ |