timer.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Common code to keep time when machine suspends.
  3. *
  4. * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
  5. *
  6. * GPLv2
  7. */
  8. #include <linux/time.h>
  9. #include <linux/sysdev.h>
  10. #include <asm/rtc.h>
  11. static unsigned long suspend_rtc_time;
  12. /*
  13. * Reset the time after a sleep.
  14. */
  15. static int timer_resume(struct sys_device *dev)
  16. {
  17. struct timeval tv;
  18. struct timespec ts;
  19. struct rtc_time cur_rtc_tm;
  20. unsigned long cur_rtc_time, diff;
  21. /* get current RTC time and convert to seconds */
  22. get_rtc_time(&cur_rtc_tm);
  23. rtc_tm_to_time(&cur_rtc_tm, &cur_rtc_time);
  24. diff = cur_rtc_time - suspend_rtc_time;
  25. /* adjust time of day by seconds that elapsed while
  26. * we were suspended */
  27. do_gettimeofday(&tv);
  28. ts.tv_sec = tv.tv_sec + diff;
  29. ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC;
  30. do_settimeofday(&ts);
  31. return 0;
  32. }
  33. static int timer_suspend(struct sys_device *dev, pm_message_t state)
  34. {
  35. struct rtc_time suspend_rtc_tm;
  36. WARN_ON(!ppc_md.get_rtc_time);
  37. get_rtc_time(&suspend_rtc_tm);
  38. rtc_tm_to_time(&suspend_rtc_tm, &suspend_rtc_time);
  39. return 0;
  40. }
  41. static struct sysdev_class timer_sysclass = {
  42. .resume = timer_resume,
  43. .suspend = timer_suspend,
  44. set_kset_name("timer"),
  45. };
  46. static struct sys_device device_timer = {
  47. .id = 0,
  48. .cls = &timer_sysclass,
  49. };
  50. static int time_init_device(void)
  51. {
  52. int error = sysdev_class_register(&timer_sysclass);
  53. if (!error)
  54. error = sysdev_register(&device_timer);
  55. return error;
  56. }
  57. device_initcall(time_init_device);