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.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 4500e347f1bb..bfda3f7f0716 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -77,6 +77,7 @@ static void tick_periodic(int cpu)
77void tick_handle_periodic(struct clock_event_device *dev) 77void tick_handle_periodic(struct clock_event_device *dev)
78{ 78{
79 int cpu = smp_processor_id(); 79 int cpu = smp_processor_id();
80 ktime_t next;
80 81
81 tick_periodic(cpu); 82 tick_periodic(cpu);
82 83
@@ -86,12 +87,12 @@ void tick_handle_periodic(struct clock_event_device *dev)
86 * Setup the next period for devices, which do not have 87 * Setup the next period for devices, which do not have
87 * periodic mode: 88 * periodic mode:
88 */ 89 */
90 next = ktime_add(dev->next_event, tick_period);
89 for (;;) { 91 for (;;) {
90 ktime_t next = ktime_add(dev->next_event, tick_period);
91
92 if (!clockevents_program_event(dev, next, ktime_get())) 92 if (!clockevents_program_event(dev, next, ktime_get()))
93 return; 93 return;
94 tick_periodic(cpu); 94 tick_periodic(cpu);
95 next = ktime_add(next, tick_period);
95 } 96 }
96} 97}
97 98
@@ -297,6 +298,29 @@ static void tick_shutdown(unsigned int *cpup)
297 spin_unlock_irqrestore(&tick_device_lock, flags); 298 spin_unlock_irqrestore(&tick_device_lock, flags);
298} 299}
299 300
301static void tick_suspend(void)
302{
303 struct tick_device *td = &__get_cpu_var(tick_cpu_device);
304 unsigned long flags;
305
306 spin_lock_irqsave(&tick_device_lock, flags);
307 clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
308 spin_unlock_irqrestore(&tick_device_lock, flags);
309}
310
311static void tick_resume(void)
312{
313 struct tick_device *td = &__get_cpu_var(tick_cpu_device);
314 unsigned long flags;
315
316 spin_lock_irqsave(&tick_device_lock, flags);
317 if (td->mode == TICKDEV_MODE_PERIODIC)
318 tick_setup_periodic(td->evtdev, 0);
319 else
320 tick_resume_oneshot();
321 spin_unlock_irqrestore(&tick_device_lock, flags);
322}
323
300/* 324/*
301 * Notification about clock event devices 325 * Notification about clock event devices
302 */ 326 */
@@ -324,6 +348,16 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
324 tick_shutdown(dev); 348 tick_shutdown(dev);
325 break; 349 break;
326 350
351 case CLOCK_EVT_NOTIFY_SUSPEND:
352 tick_suspend();
353 tick_suspend_broadcast();
354 break;
355
356 case CLOCK_EVT_NOTIFY_RESUME:
357 if (!tick_resume_broadcast())
358 tick_resume();
359 break;
360
327 default: 361 default:
328 break; 362 break;
329 } 363 }