at v2.6.23-rc2 81 lines 1.8 kB view raw
1/* 2 * Common code to keep time when machine suspends. 3 * 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 5 * 6 * GPLv2 7 */ 8 9#include <linux/time.h> 10#include <linux/sysdev.h> 11#include <asm/rtc.h> 12 13static unsigned long suspend_rtc_time; 14 15/* 16 * Reset the time after a sleep. 17 */ 18static int timer_resume(struct sys_device *dev) 19{ 20 struct timeval tv; 21 struct timespec ts; 22 struct rtc_time cur_rtc_tm; 23 unsigned long cur_rtc_time, diff; 24 25 /* get current RTC time and convert to seconds */ 26 get_rtc_time(&cur_rtc_tm); 27 cur_rtc_time = mktime(cur_rtc_tm.tm_year + 1900, 28 cur_rtc_tm.tm_mon + 1, 29 cur_rtc_tm.tm_mday, 30 cur_rtc_tm.tm_hour, 31 cur_rtc_tm.tm_min, 32 cur_rtc_tm.tm_sec); 33 34 diff = cur_rtc_time - suspend_rtc_time; 35 36 /* adjust time of day by seconds that elapsed while 37 * we were suspended */ 38 do_gettimeofday(&tv); 39 ts.tv_sec = tv.tv_sec + diff; 40 ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC; 41 do_settimeofday(&ts); 42 43 return 0; 44} 45 46static int timer_suspend(struct sys_device *dev, pm_message_t state) 47{ 48 struct rtc_time suspend_rtc_tm; 49 WARN_ON(!ppc_md.get_rtc_time); 50 51 get_rtc_time(&suspend_rtc_tm); 52 suspend_rtc_time = mktime(suspend_rtc_tm.tm_year + 1900, 53 suspend_rtc_tm.tm_mon + 1, 54 suspend_rtc_tm.tm_mday, 55 suspend_rtc_tm.tm_hour, 56 suspend_rtc_tm.tm_min, 57 suspend_rtc_tm.tm_sec); 58 59 return 0; 60} 61 62static struct sysdev_class timer_sysclass = { 63 .resume = timer_resume, 64 .suspend = timer_suspend, 65 set_kset_name("timer"), 66}; 67 68static struct sys_device device_timer = { 69 .id = 0, 70 .cls = &timer_sysclass, 71}; 72 73static int time_init_device(void) 74{ 75 int error = sysdev_class_register(&timer_sysclass); 76 if (!error) 77 error = sysdev_register(&device_timer); 78 return error; 79} 80 81device_initcall(time_init_device);