olpc-xo1-rtc.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Support for OLPC XO-1 Real Time Clock (RTC)
  3. *
  4. * Copyright (C) 2011 One Laptop per Child
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. */
  11. #include <linux/mc146818rtc.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/rtc.h>
  14. #include <linux/of.h>
  15. #include <asm/msr.h>
  16. #include <asm/olpc.h>
  17. static void rtc_wake_on(struct device *dev)
  18. {
  19. olpc_xo1_pm_wakeup_set(CS5536_PM_RTC);
  20. }
  21. static void rtc_wake_off(struct device *dev)
  22. {
  23. olpc_xo1_pm_wakeup_clear(CS5536_PM_RTC);
  24. }
  25. static struct resource rtc_platform_resource[] = {
  26. [0] = {
  27. .start = RTC_PORT(0),
  28. .end = RTC_PORT(1),
  29. .flags = IORESOURCE_IO,
  30. },
  31. [1] = {
  32. .start = RTC_IRQ,
  33. .end = RTC_IRQ,
  34. .flags = IORESOURCE_IRQ,
  35. }
  36. };
  37. static struct cmos_rtc_board_info rtc_info = {
  38. .rtc_day_alarm = 0,
  39. .rtc_mon_alarm = 0,
  40. .rtc_century = 0,
  41. .wake_on = rtc_wake_on,
  42. .wake_off = rtc_wake_off,
  43. };
  44. static struct platform_device xo1_rtc_device = {
  45. .name = "rtc_cmos",
  46. .id = -1,
  47. .num_resources = ARRAY_SIZE(rtc_platform_resource),
  48. .dev.platform_data = &rtc_info,
  49. .resource = rtc_platform_resource,
  50. };
  51. static int __init xo1_rtc_init(void)
  52. {
  53. int r;
  54. struct device_node *node;
  55. node = of_find_compatible_node(NULL, NULL, "olpc,xo1-rtc");
  56. if (!node)
  57. return 0;
  58. of_node_put(node);
  59. pr_info("olpc-xo1-rtc: Initializing OLPC XO-1 RTC\n");
  60. rdmsrl(MSR_RTC_DOMA_OFFSET, rtc_info.rtc_day_alarm);
  61. rdmsrl(MSR_RTC_MONA_OFFSET, rtc_info.rtc_mon_alarm);
  62. rdmsrl(MSR_RTC_CEN_OFFSET, rtc_info.rtc_century);
  63. r = platform_device_register(&xo1_rtc_device);
  64. if (r)
  65. return r;
  66. device_init_wakeup(&xo1_rtc_device.dev, 1);
  67. return 0;
  68. }
  69. arch_initcall(xo1_rtc_init);