olpc-xo1-rtc.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. #include <asm/x86_init.h>
  18. static void rtc_wake_on(struct device *dev)
  19. {
  20. olpc_xo1_pm_wakeup_set(CS5536_PM_RTC);
  21. }
  22. static void rtc_wake_off(struct device *dev)
  23. {
  24. olpc_xo1_pm_wakeup_clear(CS5536_PM_RTC);
  25. }
  26. static struct resource rtc_platform_resource[] = {
  27. [0] = {
  28. .start = RTC_PORT(0),
  29. .end = RTC_PORT(1),
  30. .flags = IORESOURCE_IO,
  31. },
  32. [1] = {
  33. .start = RTC_IRQ,
  34. .end = RTC_IRQ,
  35. .flags = IORESOURCE_IRQ,
  36. }
  37. };
  38. static struct cmos_rtc_board_info rtc_info = {
  39. .rtc_day_alarm = 0,
  40. .rtc_mon_alarm = 0,
  41. .rtc_century = 0,
  42. .wake_on = rtc_wake_on,
  43. .wake_off = rtc_wake_off,
  44. };
  45. static struct platform_device xo1_rtc_device = {
  46. .name = "rtc_cmos",
  47. .id = -1,
  48. .num_resources = ARRAY_SIZE(rtc_platform_resource),
  49. .dev.platform_data = &rtc_info,
  50. .resource = rtc_platform_resource,
  51. };
  52. static int __init xo1_rtc_init(void)
  53. {
  54. int r;
  55. struct device_node *node;
  56. node = of_find_compatible_node(NULL, NULL, "olpc,xo1-rtc");
  57. if (!node)
  58. return 0;
  59. of_node_put(node);
  60. pr_info("olpc-xo1-rtc: Initializing OLPC XO-1 RTC\n");
  61. rdmsrl(MSR_RTC_DOMA_OFFSET, rtc_info.rtc_day_alarm);
  62. rdmsrl(MSR_RTC_MONA_OFFSET, rtc_info.rtc_mon_alarm);
  63. rdmsrl(MSR_RTC_CEN_OFFSET, rtc_info.rtc_century);
  64. r = platform_device_register(&xo1_rtc_device);
  65. if (r)
  66. return r;
  67. x86_platform.legacy.rtc = 0;
  68. device_init_wakeup(&xo1_rtc_device.dev, 1);
  69. return 0;
  70. }
  71. arch_initcall(xo1_rtc_init);