diff options
| -rw-r--r-- | arch/arm/kernel/time.c | 33 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/pm.c | 10 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/pm.c | 12 | ||||
| -rw-r--r-- | arch/arm/mm/init.c | 1 | ||||
| -rw-r--r-- | include/asm-arm/mach/time.h | 7 |
5 files changed, 54 insertions, 9 deletions
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index c30bf05675ee..3043e6de75d9 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -304,6 +304,39 @@ int do_settimeofday(struct timespec *tv) EXPORT_SYMBOL(do_settimeofday); +/** + * save_time_delta - Save the offset between system time and RTC time + * @delta: pointer to timespec to store delta + * @rtc: pointer to timespec for current RTC time + * + * Return a delta between the system time and the RTC time, such + * that system time can be restored later with restore_time_delta() + */ +void save_time_delta(struct timespec *delta, struct timespec *rtc) +{ + set_normalized_timespec(delta, + xtime.tv_sec - rtc->tv_sec, + xtime.tv_nsec - rtc->tv_nsec); +} +EXPORT_SYMBOL(save_time_delta); + +/** + * restore_time_delta - Restore the current system time + * @delta: delta returned by save_time_delta() + * @rtc: pointer to timespec for current RTC time + */ +void restore_time_delta(struct timespec *delta, struct timespec *rtc) +{ + struct timespec ts; + + set_normalized_timespec(&ts, + delta->tv_sec + rtc->tv_sec, + delta->tv_nsec + rtc->tv_nsec); + + do_settimeofday(&ts); +} +EXPORT_SYMBOL(restore_time_delta); + void timer_tick(struct pt_regs *regs) { profile_tick(CPU_PROFILING, regs); diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 6c5fecc095e1..5e84864a8313 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -21,6 +21,7 @@ #include <asm/system.h> #include <asm/arch/pxa-regs.h> #include <asm/arch/lubbock.h> +#include <asm/mach/time.h> /* @@ -69,14 +70,16 @@ static int pxa_pm_enter(u32 state) { unsigned long sleep_save[SLEEP_SAVE_SIZE]; unsigned long checksum = 0; - unsigned long delta; + struct timespec delta, rtc; int i; if (state != PM_SUSPEND_MEM) return -EINVAL; /* preserve current time */ - delta = xtime.tv_sec - RCNR; + rtc.tv_sec = RCNR; + rtc.tv_nsec = 0; + save_time_delta(&delta, &rtc); /* save vital registers */ SAVE(OSMR0); @@ -161,7 +164,8 @@ static int pxa_pm_enter(u32 state) RESTORE(ICMR); /* restore current time */ - xtime.tv_sec = RCNR + delta; + rtc.tv_sec = RCNR; + restore_time_delta(&delta, &rtc); #ifdef DEBUG printk(KERN_DEBUG "*** made it back from resume\n"); diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index 604e703b5226..7120ec5aa726 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -30,6 +30,7 @@ #include <asm/hardware.h> #include <asm/memory.h> #include <asm/system.h> +#include <asm/mach/time.h> extern void sa1100_cpu_suspend(void); extern void sa1100_cpu_resume(void); @@ -58,14 +59,16 @@ enum { SLEEP_SAVE_SP = 0, static int sa11x0_pm_enter(u32 state) { - unsigned long sleep_save[SLEEP_SAVE_SIZE]; - unsigned long delta, gpio; + unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE]; + struct timespec delta, rtc; if (state != PM_SUSPEND_MEM) return -EINVAL; /* preserve current time */ - delta = xtime.tv_sec - RCNR; + rtc.tv_sec = RCNR; + rtc.tv_nsec = 0; + save_time_delta(&delta, &rtc); gpio = GPLR; /* save vital registers */ @@ -136,7 +139,8 @@ static int sa11x0_pm_enter(u32 state) OSCR = OSMR0 - LATCH; /* restore current time */ - xtime.tv_sec = RCNR + delta; + rtc.tv_sec = RCNR; + restore_time_delta(&delta, &rtc); return 0; } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 927b380ba7d4..d7b4441ace2d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -14,6 +14,7 @@ #include <linux/swap.h> #include <linux/init.h> #include <linux/bootmem.h> +#include <linux/mman.h> #include <linux/initrd.h> #include <asm/mach-types.h> diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h index edb6fcc6a200..51728edf7ba4 100644 --- a/include/asm-arm/mach/time.h +++ b/include/asm-arm/mach/time.h @@ -13,8 +13,11 @@ extern void (*init_arch_time)(void); extern int (*set_rtc)(void); -extern unsigned long(*gettimeoffset)(void); +extern unsigned long (*gettimeoffset)(void); -void timer_tick(struct pt_regs *); +extern void timer_tick(struct pt_regs *); + +extern void save_time_delta(struct timespec *delta, struct timespec *rtc); +extern void restore_time_delta(struct timespec *delta, struct timespec *rtc); #endif |
