rtc-tile.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright 2011 Tilera Corporation. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11. * NON INFRINGEMENT. See the GNU General Public License for
  12. * more details.
  13. *
  14. * Tilera-specific RTC driver.
  15. */
  16. #include <linux/module.h>
  17. #include <linux/device.h>
  18. #include <linux/rtc.h>
  19. #include <linux/platform_device.h>
  20. /* Platform device pointer. */
  21. static struct platform_device *tile_rtc_platform_device;
  22. /*
  23. * RTC read routine. Gets time info from RTC chip via hypervisor syscall.
  24. */
  25. static int read_rtc_time(struct device *dev, struct rtc_time *tm)
  26. {
  27. HV_RTCTime hvtm = hv_get_rtc();
  28. tm->tm_sec = hvtm.tm_sec;
  29. tm->tm_min = hvtm.tm_min;
  30. tm->tm_hour = hvtm.tm_hour;
  31. tm->tm_mday = hvtm.tm_mday;
  32. tm->tm_mon = hvtm.tm_mon;
  33. tm->tm_year = hvtm.tm_year;
  34. tm->tm_wday = 0;
  35. tm->tm_yday = 0;
  36. tm->tm_isdst = 0;
  37. if (rtc_valid_tm(tm) < 0)
  38. dev_warn(dev, "Read invalid date/time from RTC\n");
  39. return 0;
  40. }
  41. /*
  42. * RTC write routine. Sends time info to hypervisor via syscall, to be
  43. * written to RTC chip.
  44. */
  45. static int set_rtc_time(struct device *dev, struct rtc_time *tm)
  46. {
  47. HV_RTCTime hvtm;
  48. hvtm.tm_sec = tm->tm_sec;
  49. hvtm.tm_min = tm->tm_min;
  50. hvtm.tm_hour = tm->tm_hour;
  51. hvtm.tm_mday = tm->tm_mday;
  52. hvtm.tm_mon = tm->tm_mon;
  53. hvtm.tm_year = tm->tm_year;
  54. hv_set_rtc(hvtm);
  55. return 0;
  56. }
  57. /*
  58. * RTC read/write ops.
  59. */
  60. static const struct rtc_class_ops tile_rtc_ops = {
  61. .read_time = read_rtc_time,
  62. .set_time = set_rtc_time,
  63. };
  64. /*
  65. * Device probe routine.
  66. */
  67. static int tile_rtc_probe(struct platform_device *dev)
  68. {
  69. struct rtc_device *rtc;
  70. rtc = devm_rtc_device_register(&dev->dev, "tile",
  71. &tile_rtc_ops, THIS_MODULE);
  72. if (IS_ERR(rtc))
  73. return PTR_ERR(rtc);
  74. platform_set_drvdata(dev, rtc);
  75. return 0;
  76. }
  77. static struct platform_driver tile_rtc_platform_driver = {
  78. .driver = {
  79. .name = "rtc-tile",
  80. },
  81. .probe = tile_rtc_probe,
  82. };
  83. /*
  84. * Driver init routine.
  85. */
  86. static int __init tile_rtc_driver_init(void)
  87. {
  88. int err;
  89. err = platform_driver_register(&tile_rtc_platform_driver);
  90. if (err)
  91. return err;
  92. tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0);
  93. if (tile_rtc_platform_device == NULL) {
  94. err = -ENOMEM;
  95. goto exit_driver_unregister;
  96. }
  97. err = platform_device_add(tile_rtc_platform_device);
  98. if (err)
  99. goto exit_device_put;
  100. return 0;
  101. exit_device_put:
  102. platform_device_put(tile_rtc_platform_device);
  103. exit_driver_unregister:
  104. platform_driver_unregister(&tile_rtc_platform_driver);
  105. return err;
  106. }
  107. /*
  108. * Driver cleanup routine.
  109. */
  110. static void __exit tile_rtc_driver_exit(void)
  111. {
  112. platform_device_unregister(tile_rtc_platform_device);
  113. platform_driver_unregister(&tile_rtc_platform_driver);
  114. }
  115. module_init(tile_rtc_driver_init);
  116. module_exit(tile_rtc_driver_exit);
  117. MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver");
  118. MODULE_LICENSE("GPL");
  119. MODULE_ALIAS("platform:rtc-tile");