15 #include <linux/kernel.h>
19 #include <linux/slab.h>
21 #define APBT_MIN_PERIOD 4
22 #define APBT_MIN_DELTA_USEC 200
24 #define APBTMR_N_LOAD_COUNT 0x00
25 #define APBTMR_N_CURRENT_VALUE 0x04
26 #define APBTMR_N_CONTROL 0x08
27 #define APBTMR_N_EOI 0x0c
28 #define APBTMR_N_INT_STATUS 0x10
30 #define APBTMRS_INT_STATUS 0xa0
31 #define APBTMRS_EOI 0xa4
32 #define APBTMRS_RAW_INT_STATUS 0xa8
33 #define APBTMRS_COMP_VERSION 0xac
35 #define APBTMR_CONTROL_ENABLE (1 << 0)
37 #define APBTMR_CONTROL_MODE_PERIODIC (1 << 1)
38 #define APBTMR_CONTROL_INT (1 << 2)
41 ced_to_dw_apb_ced(
struct clock_event_device *
evt)
79 apbt_disable_int(&dw_ced->
timer);
89 struct clock_event_device *
evt =
data;
92 if (!evt->event_handler) {
93 pr_info(
"Spurious APBT timer interrupt %d", irq);
100 evt->event_handler(evt);
113 static void apbt_set_mode(
enum clock_event_mode
mode,
114 struct clock_event_device *evt)
124 case CLOCK_EVT_MODE_PERIODIC:
136 pr_debug(
"Setting clock period %lu for HZ %d\n", period,
HZ);
142 case CLOCK_EVT_MODE_ONESHOT:
166 case CLOCK_EVT_MODE_UNUSED:
167 case CLOCK_EVT_MODE_SHUTDOWN:
173 case CLOCK_EVT_MODE_RESUME:
174 apbt_enable_int(&dw_ced->
timer);
179 static int apbt_next_event(
unsigned long delta,
180 struct clock_event_device *evt)
225 dw_ced->
timer.base = base;
226 dw_ced->
timer.irq = irq;
234 dw_ced->
ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
235 dw_ced->
ced.set_mode = apbt_set_mode;
236 dw_ced->
ced.set_next_event = apbt_next_event;
237 dw_ced->
ced.irq = dw_ced->
timer.irq;
238 dw_ced->
ced.rating = rating;
242 dw_ced->
irqaction.handler = dw_apb_clockevent_irq;
249 dw_ced->
eoi = apbt_eoi;
252 pr_err(
"failed to request timer irq\n");
289 apbt_enable_int(&dw_ced->
timer);
321 unsigned long current_count;
323 clocksource_to_dw_apb_clocksource(cs);
327 return (
cycle_t)~current_count;
330 static void apbt_restart_clocksource(
struct clocksource *cs)
333 clocksource_to_dw_apb_clocksource(cs);
359 dw_cs->
timer.base = base;
362 dw_cs->
cs.rating = rating;
363 dw_cs->
cs.read = __apbt_read_clocksource;
366 dw_cs->
cs.resume = apbt_restart_clocksource;
378 clocksource_register_hz(&dw_cs->
cs, dw_cs->
timer.freq);