timer-goldfish.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/interrupt.h>
  3. #include <linux/ioport.h>
  4. #include <linux/clocksource.h>
  5. #include <linux/clockchips.h>
  6. #include <linux/module.h>
  7. #include <linux/slab.h>
  8. #include <linux/goldfish.h>
  9. #include <clocksource/timer-goldfish.h>
  10. struct goldfish_timer {
  11. struct clocksource cs;
  12. struct clock_event_device ced;
  13. struct resource res;
  14. void __iomem *base;
  15. };
  16. static struct goldfish_timer *ced_to_gf(struct clock_event_device *ced)
  17. {
  18. return container_of(ced, struct goldfish_timer, ced);
  19. }
  20. static struct goldfish_timer *cs_to_gf(struct clocksource *cs)
  21. {
  22. return container_of(cs, struct goldfish_timer, cs);
  23. }
  24. static u64 goldfish_timer_read(struct clocksource *cs)
  25. {
  26. struct goldfish_timer *timerdrv = cs_to_gf(cs);
  27. void __iomem *base = timerdrv->base;
  28. u32 time_low, time_high;
  29. u64 ticks;
  30. /*
  31. * time_low: get low bits of current time and update time_high
  32. * time_high: get high bits of time at last time_low read
  33. */
  34. time_low = gf_ioread32(base + TIMER_TIME_LOW);
  35. time_high = gf_ioread32(base + TIMER_TIME_HIGH);
  36. ticks = ((u64)time_high << 32) | time_low;
  37. return ticks;
  38. }
  39. static int goldfish_timer_set_oneshot(struct clock_event_device *evt)
  40. {
  41. struct goldfish_timer *timerdrv = ced_to_gf(evt);
  42. void __iomem *base = timerdrv->base;
  43. gf_iowrite32(0, base + TIMER_ALARM_HIGH);
  44. gf_iowrite32(0, base + TIMER_ALARM_LOW);
  45. gf_iowrite32(1, base + TIMER_IRQ_ENABLED);
  46. return 0;
  47. }
  48. static int goldfish_timer_shutdown(struct clock_event_device *evt)
  49. {
  50. struct goldfish_timer *timerdrv = ced_to_gf(evt);
  51. void __iomem *base = timerdrv->base;
  52. gf_iowrite32(0, base + TIMER_IRQ_ENABLED);
  53. return 0;
  54. }
  55. static int goldfish_timer_next_event(unsigned long delta,
  56. struct clock_event_device *evt)
  57. {
  58. struct goldfish_timer *timerdrv = ced_to_gf(evt);
  59. void __iomem *base = timerdrv->base;
  60. u64 now;
  61. now = goldfish_timer_read(&timerdrv->cs);
  62. now += delta;
  63. gf_iowrite32(upper_32_bits(now), base + TIMER_ALARM_HIGH);
  64. gf_iowrite32(lower_32_bits(now), base + TIMER_ALARM_LOW);
  65. return 0;
  66. }
  67. static irqreturn_t goldfish_timer_irq(int irq, void *dev_id)
  68. {
  69. struct goldfish_timer *timerdrv = dev_id;
  70. struct clock_event_device *evt = &timerdrv->ced;
  71. void __iomem *base = timerdrv->base;
  72. gf_iowrite32(1, base + TIMER_CLEAR_INTERRUPT);
  73. evt->event_handler(evt);
  74. return IRQ_HANDLED;
  75. }
  76. int __init goldfish_timer_init(int irq, void __iomem *base)
  77. {
  78. struct goldfish_timer *timerdrv;
  79. int ret;
  80. timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL);
  81. if (!timerdrv)
  82. return -ENOMEM;
  83. timerdrv->base = base;
  84. timerdrv->ced = (struct clock_event_device){
  85. .name = "goldfish_timer",
  86. .features = CLOCK_EVT_FEAT_ONESHOT,
  87. .set_state_shutdown = goldfish_timer_shutdown,
  88. .set_state_oneshot = goldfish_timer_set_oneshot,
  89. .set_next_event = goldfish_timer_next_event,
  90. };
  91. timerdrv->res = (struct resource){
  92. .name = "goldfish_timer",
  93. .start = (unsigned long)base,
  94. .end = (unsigned long)base + 0xfff,
  95. };
  96. ret = request_resource(&iomem_resource, &timerdrv->res);
  97. if (ret) {
  98. pr_err("Cannot allocate '%s' resource\n", timerdrv->res.name);
  99. return ret;
  100. }
  101. timerdrv->cs = (struct clocksource){
  102. .name = "goldfish_timer",
  103. .rating = 400,
  104. .read = goldfish_timer_read,
  105. .mask = CLOCKSOURCE_MASK(64),
  106. .flags = 0,
  107. .max_idle_ns = LONG_MAX,
  108. };
  109. clocksource_register_hz(&timerdrv->cs, NSEC_PER_SEC);
  110. ret = request_irq(irq, goldfish_timer_irq, IRQF_TIMER,
  111. "goldfish_timer", timerdrv);
  112. if (ret) {
  113. pr_err("Couldn't register goldfish-timer interrupt\n");
  114. return ret;
  115. }
  116. clockevents_config_and_register(&timerdrv->ced, NSEC_PER_SEC,
  117. 1, 0xffffffff);
  118. return 0;
  119. }