aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2005-01-14 23:24:20 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 23:24:20 -0800
commite0eabf37d0d67c0f132090d8f59f0307743a3084 (patch)
treed68ed906a59834fa1c36b4404ba4c4c0d5d646fd /arch
parentba6d1ee6b671e2a2fce9604ac87d672cc402e967 (diff)
downloadhistory-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.c14
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;
}