diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2005-01-14 23:24:20 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-14 23:24:20 -0800 |
commit | e0eabf37d0d67c0f132090d8f59f0307743a3084 (patch) | |
tree | d68ed906a59834fa1c36b4404ba4c4c0d5d646fd /arch | |
parent | ba6d1ee6b671e2a2fce9604ac87d672cc402e967 (diff) | |
download | history-e0eabf37d0d67c0f132090d8f59f0307743a3084.tar.gz |
[PATCH] Fix a bug in timer_suspend() on x86_64
This patch is intended to fix a bug in timer_suspend() on x86_64 that
causes hard lockups on suspend with swsusp and provide some optimizations.
It is based on the Nigel Cunningham's patches to to reduce delay in
arch/kernel/time.c.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Acked-by: Nigel Cunningham <ncunningham@linuxmail.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/kernel/time.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 8e24b019d5e274..6482b07e9cf4f4 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -955,16 +955,19 @@ void __init time_init_smp(void) __setup("report_lost_ticks", time_setup); -static long clock_cmos_diff, sleep_start; +static long clock_cmos_diff; +static unsigned long sleep_start; static int timer_suspend(struct sys_device *dev, u32 state) { /* * Estimate time zone so that set_time can update the clock */ - clock_cmos_diff = -get_cmos_time(); + long cmos_time = get_cmos_time(); + + clock_cmos_diff = -cmos_time; clock_cmos_diff += get_seconds(); - sleep_start = jiffies; + sleep_start = cmos_time; return 0; } @@ -973,7 +976,7 @@ static int timer_resume(struct sys_device *dev) unsigned long flags; unsigned long sec; unsigned long ctime = get_cmos_time(); - unsigned long sleep_length = ctime - sleep_start; + unsigned long sleep_length = (ctime - sleep_start) * HZ; if (vxtime.hpet_address) hpet_reenable(); @@ -983,7 +986,8 @@ static int timer_resume(struct sys_device *dev) xtime.tv_sec = sec; xtime.tv_nsec = 0; write_sequnlock_irqrestore(&xtime_lock,flags); - jiffies += sleep_length * HZ; + jiffies += sleep_length; + wall_jiffies += sleep_length; return 0; } |