1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/interrupt.h>
4 #include <linux/ioport.h>
5 #include <linux/clocksource.h>
6 #include <linux/clockchips.h>
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/goldfish.h>
10 #include <clocksource/timer-goldfish.h>
12 struct goldfish_timer
{
13 struct clocksource cs
;
14 struct clock_event_device ced
;
19 static struct goldfish_timer
*ced_to_gf(struct clock_event_device
*ced
)
21 return container_of(ced
, struct goldfish_timer
, ced
);
24 static struct goldfish_timer
*cs_to_gf(struct clocksource
*cs
)
26 return container_of(cs
, struct goldfish_timer
, cs
);
29 static u64
goldfish_timer_read(struct clocksource
*cs
)
31 struct goldfish_timer
*timerdrv
= cs_to_gf(cs
);
32 void __iomem
*base
= timerdrv
->base
;
33 u32 time_low
, time_high
;
37 * time_low: get low bits of current time and update time_high
38 * time_high: get high bits of time at last time_low read
40 time_low
= gf_ioread32(base
+ TIMER_TIME_LOW
);
41 time_high
= gf_ioread32(base
+ TIMER_TIME_HIGH
);
43 ticks
= ((u64
)time_high
<< 32) | time_low
;
48 static int goldfish_timer_set_oneshot(struct clock_event_device
*evt
)
50 struct goldfish_timer
*timerdrv
= ced_to_gf(evt
);
51 void __iomem
*base
= timerdrv
->base
;
53 gf_iowrite32(0, base
+ TIMER_ALARM_HIGH
);
54 gf_iowrite32(0, base
+ TIMER_ALARM_LOW
);
55 gf_iowrite32(1, base
+ TIMER_IRQ_ENABLED
);
60 static int goldfish_timer_shutdown(struct clock_event_device
*evt
)
62 struct goldfish_timer
*timerdrv
= ced_to_gf(evt
);
63 void __iomem
*base
= timerdrv
->base
;
65 gf_iowrite32(0, base
+ TIMER_IRQ_ENABLED
);
70 static int goldfish_timer_next_event(unsigned long delta
,
71 struct clock_event_device
*evt
)
73 struct goldfish_timer
*timerdrv
= ced_to_gf(evt
);
74 void __iomem
*base
= timerdrv
->base
;
77 now
= goldfish_timer_read(&timerdrv
->cs
);
81 gf_iowrite32(upper_32_bits(now
), base
+ TIMER_ALARM_HIGH
);
82 gf_iowrite32(lower_32_bits(now
), base
+ TIMER_ALARM_LOW
);
87 static irqreturn_t
goldfish_timer_irq(int irq
, void *dev_id
)
89 struct goldfish_timer
*timerdrv
= dev_id
;
90 struct clock_event_device
*evt
= &timerdrv
->ced
;
91 void __iomem
*base
= timerdrv
->base
;
93 gf_iowrite32(1, base
+ TIMER_CLEAR_INTERRUPT
);
95 evt
->event_handler(evt
);
100 int __init
goldfish_timer_init(int irq
, void __iomem
*base
)
102 struct goldfish_timer
*timerdrv
;
105 timerdrv
= kzalloc(sizeof(*timerdrv
), GFP_KERNEL
);
109 timerdrv
->base
= base
;
111 timerdrv
->ced
= (struct clock_event_device
){
112 .name
= "goldfish_timer",
113 .features
= CLOCK_EVT_FEAT_ONESHOT
,
114 .set_state_shutdown
= goldfish_timer_shutdown
,
115 .set_state_oneshot
= goldfish_timer_set_oneshot
,
116 .set_next_event
= goldfish_timer_next_event
,
119 timerdrv
->res
= (struct resource
){
120 .name
= "goldfish_timer",
121 .start
= (unsigned long)base
,
122 .end
= (unsigned long)base
+ 0xfff,
125 ret
= request_resource(&iomem_resource
, &timerdrv
->res
);
127 pr_err("Cannot allocate '%s' resource\n", timerdrv
->res
.name
);
131 timerdrv
->cs
= (struct clocksource
){
132 .name
= "goldfish_timer",
134 .read
= goldfish_timer_read
,
135 .mask
= CLOCKSOURCE_MASK(64),
137 .max_idle_ns
= LONG_MAX
,
140 clocksource_register_hz(&timerdrv
->cs
, NSEC_PER_SEC
);
142 ret
= request_irq(irq
, goldfish_timer_irq
, IRQF_TIMER
,
143 "goldfish_timer", timerdrv
);
145 pr_err("Couldn't register goldfish-timer interrupt\n");
149 clockevents_config_and_register(&timerdrv
->ced
, NSEC_PER_SEC
,