aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/tick-common.c')
-rw-r--r--kernel/time/tick-common.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 48167a6ae55c..c35d449be031 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -34,6 +34,16 @@ ktime_t tick_period;
34static int tick_do_timer_cpu = -1; 34static int tick_do_timer_cpu = -1;
35DEFINE_SPINLOCK(tick_device_lock); 35DEFINE_SPINLOCK(tick_device_lock);
36 36
37/**
38 * tick_is_oneshot_available - check for a oneshot capable event device
39 */
40int tick_is_oneshot_available(void)
41{
42 struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
43
44 return dev && (dev->features & CLOCK_EVT_FEAT_ONESHOT);
45}
46
37/* 47/*
38 * Periodic tick 48 * Periodic tick
39 */ 49 */
@@ -162,6 +172,8 @@ static void tick_setup_device(struct tick_device *td,
162 172
163 if (td->mode == TICKDEV_MODE_PERIODIC) 173 if (td->mode == TICKDEV_MODE_PERIODIC)
164 tick_setup_periodic(newdev, 0); 174 tick_setup_periodic(newdev, 0);
175 else
176 tick_setup_oneshot(newdev, handler, next_event);
165} 177}
166 178
167/* 179/*
@@ -209,6 +221,12 @@ static int tick_check_new_device(struct clock_event_device *newdev)
209 */ 221 */
210 if (curdev) { 222 if (curdev) {
211 /* 223 /*
224 * Prefer one shot capable devices !
225 */
226 if ((curdev->features & CLOCK_EVT_FEAT_ONESHOT) &&
227 !(newdev->features & CLOCK_EVT_FEAT_ONESHOT))
228 goto out_bc;
229 /*
212 * Check the rating 230 * Check the rating
213 */ 231 */
214 if (curdev->rating >= newdev->rating) 232 if (curdev->rating >= newdev->rating)
@@ -226,6 +244,8 @@ static int tick_check_new_device(struct clock_event_device *newdev)
226 } 244 }
227 clockevents_exchange_device(curdev, newdev); 245 clockevents_exchange_device(curdev, newdev);
228 tick_setup_device(td, newdev, cpu, cpumask); 246 tick_setup_device(td, newdev, cpu, cpumask);
247 if (newdev->features & CLOCK_EVT_FEAT_ONESHOT)
248 tick_oneshot_notify();
229 249
230 spin_unlock_irqrestore(&tick_device_lock, flags); 250 spin_unlock_irqrestore(&tick_device_lock, flags);
231 return NOTIFY_STOP; 251 return NOTIFY_STOP;
@@ -285,7 +305,13 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
285 tick_broadcast_on_off(reason, dev); 305 tick_broadcast_on_off(reason, dev);
286 break; 306 break;
287 307
308 case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
309 case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
310 tick_broadcast_oneshot_control(reason);
311 break;
312
288 case CLOCK_EVT_NOTIFY_CPU_DEAD: 313 case CLOCK_EVT_NOTIFY_CPU_DEAD:
314 tick_shutdown_broadcast_oneshot(dev);
289 tick_shutdown_broadcast(dev); 315 tick_shutdown_broadcast(dev);
290 tick_shutdown(dev); 316 tick_shutdown(dev);
291 break; 317 break;