0001
0002
0003 #include <linux/interrupt.h>
0004 #include <linux/ioport.h>
0005 #include <linux/clocksource.h>
0006 #include <linux/clockchips.h>
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009 #include <linux/goldfish.h>
0010 #include <clocksource/timer-goldfish.h>
0011
0012 struct goldfish_timer {
0013 struct clocksource cs;
0014 struct clock_event_device ced;
0015 struct resource res;
0016 void __iomem *base;
0017 };
0018
0019 static struct goldfish_timer *ced_to_gf(struct clock_event_device *ced)
0020 {
0021 return container_of(ced, struct goldfish_timer, ced);
0022 }
0023
0024 static struct goldfish_timer *cs_to_gf(struct clocksource *cs)
0025 {
0026 return container_of(cs, struct goldfish_timer, cs);
0027 }
0028
0029 static u64 goldfish_timer_read(struct clocksource *cs)
0030 {
0031 struct goldfish_timer *timerdrv = cs_to_gf(cs);
0032 void __iomem *base = timerdrv->base;
0033 u32 time_low, time_high;
0034 u64 ticks;
0035
0036
0037
0038
0039
0040 time_low = gf_ioread32(base + TIMER_TIME_LOW);
0041 time_high = gf_ioread32(base + TIMER_TIME_HIGH);
0042
0043 ticks = ((u64)time_high << 32) | time_low;
0044
0045 return ticks;
0046 }
0047
0048 static int goldfish_timer_set_oneshot(struct clock_event_device *evt)
0049 {
0050 struct goldfish_timer *timerdrv = ced_to_gf(evt);
0051 void __iomem *base = timerdrv->base;
0052
0053 gf_iowrite32(0, base + TIMER_ALARM_HIGH);
0054 gf_iowrite32(0, base + TIMER_ALARM_LOW);
0055 gf_iowrite32(1, base + TIMER_IRQ_ENABLED);
0056
0057 return 0;
0058 }
0059
0060 static int goldfish_timer_shutdown(struct clock_event_device *evt)
0061 {
0062 struct goldfish_timer *timerdrv = ced_to_gf(evt);
0063 void __iomem *base = timerdrv->base;
0064
0065 gf_iowrite32(0, base + TIMER_IRQ_ENABLED);
0066
0067 return 0;
0068 }
0069
0070 static int goldfish_timer_next_event(unsigned long delta,
0071 struct clock_event_device *evt)
0072 {
0073 struct goldfish_timer *timerdrv = ced_to_gf(evt);
0074 void __iomem *base = timerdrv->base;
0075 u64 now;
0076
0077 now = goldfish_timer_read(&timerdrv->cs);
0078
0079 now += delta;
0080
0081 gf_iowrite32(upper_32_bits(now), base + TIMER_ALARM_HIGH);
0082 gf_iowrite32(lower_32_bits(now), base + TIMER_ALARM_LOW);
0083
0084 return 0;
0085 }
0086
0087 static irqreturn_t goldfish_timer_irq(int irq, void *dev_id)
0088 {
0089 struct goldfish_timer *timerdrv = dev_id;
0090 struct clock_event_device *evt = &timerdrv->ced;
0091 void __iomem *base = timerdrv->base;
0092
0093 gf_iowrite32(1, base + TIMER_CLEAR_INTERRUPT);
0094
0095 evt->event_handler(evt);
0096
0097 return IRQ_HANDLED;
0098 }
0099
0100 int __init goldfish_timer_init(int irq, void __iomem *base)
0101 {
0102 struct goldfish_timer *timerdrv;
0103 int ret;
0104
0105 timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL);
0106 if (!timerdrv)
0107 return -ENOMEM;
0108
0109 timerdrv->base = base;
0110
0111 timerdrv->ced = (struct clock_event_device){
0112 .name = "goldfish_timer",
0113 .features = CLOCK_EVT_FEAT_ONESHOT,
0114 .set_state_shutdown = goldfish_timer_shutdown,
0115 .set_state_oneshot = goldfish_timer_set_oneshot,
0116 .set_next_event = goldfish_timer_next_event,
0117 };
0118
0119 timerdrv->res = (struct resource){
0120 .name = "goldfish_timer",
0121 .start = (unsigned long)base,
0122 .end = (unsigned long)base + 0xfff,
0123 };
0124
0125 ret = request_resource(&iomem_resource, &timerdrv->res);
0126 if (ret) {
0127 pr_err("Cannot allocate '%s' resource\n", timerdrv->res.name);
0128 return ret;
0129 }
0130
0131 timerdrv->cs = (struct clocksource){
0132 .name = "goldfish_timer",
0133 .rating = 400,
0134 .read = goldfish_timer_read,
0135 .mask = CLOCKSOURCE_MASK(64),
0136 .flags = 0,
0137 .max_idle_ns = LONG_MAX,
0138 };
0139
0140 clocksource_register_hz(&timerdrv->cs, NSEC_PER_SEC);
0141
0142 ret = request_irq(irq, goldfish_timer_irq, IRQF_TIMER,
0143 "goldfish_timer", timerdrv);
0144 if (ret) {
0145 pr_err("Couldn't register goldfish-timer interrupt\n");
0146 return ret;
0147 }
0148
0149 clockevents_config_and_register(&timerdrv->ced, NSEC_PER_SEC,
0150 1, 0xffffffff);
0151
0152 return 0;
0153 }