aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-broadcast.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2007-07-21 07:37:35 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-21 20:49:15 -0400
commit5590a536c0bc403fc73908c66c1c88cbed735ecb (patch)
treee07b89628885da86706a2ba0ce9d50cd7f4a0dfc /kernel/time/tick-broadcast.c
parent18de5bc4c1f1f1fa5e14f354a7603bd6e9d4e3b6 (diff)
clockevents: fix device replacement
When a device is replaced by a better rated device, then the broadcast mode needs to be evaluated again. When the new device has no requirement for broadcasting, then the broadcast bits for the CPU must be cleared. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: john stultz <johnstul@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r--kernel/time/tick-broadcast.c29
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;
31static cpumask_t tick_broadcast_mask; 31static cpumask_t tick_broadcast_mask;
32static DEFINE_SPINLOCK(tick_broadcast_lock); 32static DEFINE_SPINLOCK(tick_broadcast_lock);
33 33
34#ifdef CONFIG_TICK_ONESHOT
35static void tick_broadcast_clear_oneshot(int cpu);
36#else
37static 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 */
512static 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 */