diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2007-03-06 08:25:42 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-06 18:30:24 +0100 |
commit | 6321dd60c76b2e12383bc06046288b15397ed3a0 (patch) | |
tree | 4cea63e69ce4f6f5f7f94fc6905063efdde7974e /kernel/time/tick-broadcast.c | |
parent | [PATCH] paravirt: re-enable COMPAT_VDSO (diff) | |
download | linux-6321dd60c76b2e12383bc06046288b15397ed3a0.tar.xz linux-6321dd60c76b2e12383bc06046288b15397ed3a0.zip |
[PATCH] Save/restore periodic tick information over suspend/resume
The programming of periodic tick devices needs to be saved/restored
across suspend/resume - otherwise we might end up with a system coming
up that relies on getting a PIT (or HPET) interrupt, while those devices
default to 'no interrupts' after powerup. (To confuse things it worked
to a certain degree on some systems because the lapic gets initialized
as a side-effect of SMP bootup.)
This suspend / resume thing was dropped unintentionally during the
last-minute -mm code reshuffling.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r-- | kernel/time/tick-broadcast.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 12b3efeb9f6f..5567745470f7 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -284,6 +284,42 @@ void tick_shutdown_broadcast(unsigned int *cpup) spin_unlock_irqrestore(&tick_broadcast_lock, flags); } +void tick_suspend_broadcast(void) +{ + struct clock_event_device *bc; + unsigned long flags; + + spin_lock_irqsave(&tick_broadcast_lock, flags); + + bc = tick_broadcast_device.evtdev; + if (bc && tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) + clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); + + spin_unlock_irqrestore(&tick_broadcast_lock, flags); +} + +int tick_resume_broadcast(void) +{ + struct clock_event_device *bc; + unsigned long flags; + int broadcast = 0; + + spin_lock_irqsave(&tick_broadcast_lock, flags); + + bc = tick_broadcast_device.evtdev; + if (bc) { + if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC && + !cpus_empty(tick_broadcast_mask)) + tick_broadcast_start_periodic(bc); + + broadcast = cpu_isset(smp_processor_id(), tick_broadcast_mask); + } + spin_unlock_irqrestore(&tick_broadcast_lock, flags); + + return broadcast; +} + + #ifdef CONFIG_TICK_ONESHOT static cpumask_t tick_broadcast_oneshot_mask; |