rtc-tile.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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 __devinit tile_rtc_probe(struct platform_device *dev)
  68. {
  69. struct rtc_device *rtc;
  70. rtc = rtc_device_register("tile",
  71. &dev->dev, &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. /*
  78. * Device cleanup routine.
  79. */
  80. static int __devexit tile_rtc_remove(struct platform_device *dev)
  81. {
  82. struct rtc_device *rtc = platform_get_drvdata(dev);
  83. if (rtc)
  84. rtc_device_unregister(rtc);
  85. platform_set_drvdata(dev, NULL);
  86. return 0;
  87. }
  88. static struct platform_driver tile_rtc_platform_driver = {
  89. .driver = {
  90. .name = "rtc-tile",
  91. .owner = THIS_MODULE,
  92. },
  93. .probe = tile_rtc_probe,
  94. .remove = __devexit_p(tile_rtc_remove),
  95. };
  96. /*
  97. * Driver init routine.
  98. */
  99. static int __init tile_rtc_driver_init(void)
  100. {
  101. int err;
  102. err = platform_driver_register(&tile_rtc_platform_driver);
  103. if (err)
  104. return err;
  105. tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0);
  106. if (tile_rtc_platform_device == NULL) {
  107. err = -ENOMEM;
  108. goto exit_driver_unregister;
  109. }
  110. err = platform_device_add(tile_rtc_platform_device);
  111. if (err)
  112. goto exit_device_put;
  113. return 0;
  114. exit_device_put:
  115. platform_device_put(tile_rtc_platform_device);
  116. exit_driver_unregister:
  117. platform_driver_unregister(&tile_rtc_platform_driver);
  118. return err;
  119. }
  120. /*
  121. * Driver cleanup routine.
  122. */
  123. static void __exit tile_rtc_driver_exit(void)
  124. {
  125. platform_driver_unregister(&tile_rtc_platform_driver);
  126. }
  127. module_init(tile_rtc_driver_init);
  128. module_exit(tile_rtc_driver_exit);
  129. MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver");
  130. MODULE_LICENSE("GPL");
  131. MODULE_ALIAS("platform:rtc-tile");