timer.c 1.4 KB

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