diff options
Diffstat (limited to 'kernel/time/tick-common.c')
-rw-r--r-- | kernel/time/tick-common.c | 26 |
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; | |||
34 | static int tick_do_timer_cpu = -1; | 34 | static int tick_do_timer_cpu = -1; |
35 | DEFINE_SPINLOCK(tick_device_lock); | 35 | DEFINE_SPINLOCK(tick_device_lock); |
36 | 36 | ||
37 | /** | ||
38 | * tick_is_oneshot_available - check for a oneshot capable event device | ||
39 | */ | ||
40 | int 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; |