13 #include <linux/sched.h>
29 #include <mach/irqs.h>
33 #define TICK_BASE_CNT 1
40 static unsigned long clk_rate;
41 static unsigned int mct_int_type;
44 struct clock_event_device *
evt;
49 static void exynos4_mct_write(
unsigned int value,
void *
addr)
113 panic(
"MCT hangs after writing %d (addr:0x%08x)\n", value, (
u32)addr);
117 static void exynos4_mct_frc_start(
u32 hi,
u32 lo)
140 return ((
cycle_t)hi << 32) | lo;
143 static void exynos4_frc_resume(
struct clocksource *cs)
145 exynos4_mct_frc_start(0, 0);
151 .read = exynos4_frc_read,
154 .resume = exynos4_frc_resume,
157 static void __init exynos4_clocksource_init(
void)
159 exynos4_mct_frc_start(0, 0);
161 if (clocksource_register_hz(&mct_frc, clk_rate))
162 panic(
"%s: can't register clocksource\n", mct_frc.
name);
165 static void exynos4_mct_comp0_stop(
void)
176 static void exynos4_mct_comp0_start(
enum clock_event_mode
mode,
177 unsigned long cycles)
184 if (mode == CLOCK_EVT_MODE_PERIODIC) {
189 comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
199 static int exynos4_comp_set_next_event(
unsigned long cycles,
200 struct clock_event_device *
evt)
202 exynos4_mct_comp0_start(evt->mode, cycles);
207 static void exynos4_comp_set_mode(
enum clock_event_mode mode,
208 struct clock_event_device *
evt)
210 unsigned long cycles_per_jiffy;
211 exynos4_mct_comp0_stop();
214 case CLOCK_EVT_MODE_PERIODIC:
217 exynos4_mct_comp0_start(mode, cycles_per_jiffy);
220 case CLOCK_EVT_MODE_ONESHOT:
221 case CLOCK_EVT_MODE_UNUSED:
222 case CLOCK_EVT_MODE_SHUTDOWN:
223 case CLOCK_EVT_MODE_RESUME:
228 static struct clock_event_device mct_comp_device = {
230 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
232 .set_next_event = exynos4_comp_set_next_event,
233 .set_mode = exynos4_comp_set_mode,
238 struct clock_event_device *evt =
dev_id;
242 evt->event_handler(evt);
247 static struct irqaction mct_comp_event_irq = {
248 .name =
"mct_comp_irq",
250 .handler = exynos4_mct_comp_isr,
251 .dev_id = &mct_comp_device,
254 static void exynos4_clockevent_init(
void)
256 clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
257 mct_comp_device.max_delta_ns =
259 mct_comp_device.min_delta_ns =
270 #ifdef CONFIG_LOCAL_TIMERS
284 exynos4_mct_write(tmp, addr);
288 static void exynos4_mct_tick_start(
unsigned long cycles,
293 exynos4_mct_tick_stop(mevt);
295 tmp = (1 << 31) | cycles;
309 static int exynos4_tick_set_next_event(
unsigned long cycles,
310 struct clock_event_device *evt)
314 exynos4_mct_tick_start(cycles, mevt);
319 static inline void exynos4_tick_set_mode(
enum clock_event_mode mode,
320 struct clock_event_device *evt)
323 unsigned long cycles_per_jiffy;
325 exynos4_mct_tick_stop(mevt);
328 case CLOCK_EVT_MODE_PERIODIC:
331 exynos4_mct_tick_start(cycles_per_jiffy, mevt);
334 case CLOCK_EVT_MODE_ONESHOT:
335 case CLOCK_EVT_MODE_UNUSED:
336 case CLOCK_EVT_MODE_SHUTDOWN:
337 case CLOCK_EVT_MODE_RESUME:
344 struct clock_event_device *evt = mevt->
evt;
351 if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
352 exynos4_mct_tick_stop(mevt);
363 static irqreturn_t exynos4_mct_tick_isr(
int irq,
void *dev_id)
366 struct clock_event_device *evt = mevt->
evt;
368 exynos4_mct_tick_clear(mevt);
370 evt->event_handler(evt);
375 static struct irqaction mct_tick0_event_irq = {
376 .
name =
"mct_tick0_irq",
378 .handler = exynos4_mct_tick_isr,
381 static struct irqaction mct_tick1_event_irq = {
382 .
name =
"mct_tick1_irq",
384 .handler = exynos4_mct_tick_isr,
387 static int __cpuinit exynos4_local_timer_setup(
struct clock_event_device *evt)
399 evt->name = mevt->
name;
401 evt->set_next_event = exynos4_tick_set_next_event;
402 evt->set_mode = exynos4_tick_set_mode;
403 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
406 clockevents_calc_mult_shift(evt, clk_rate / (
TICK_BASE_CNT + 1), 5);
420 mct_tick0_event_irq.
dev_id = mevt;
421 evt->irq = mct_lx_irq;
422 setup_irq(mct_lx_irq, &mct_tick0_event_irq);
426 mct_tick1_event_irq.
dev_id = mevt;
427 evt->irq = mct_lx_irq;
428 setup_irq(mct_lx_irq, &mct_tick1_event_irq);
438 static void exynos4_local_timer_stop(
struct clock_event_device *evt)
441 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
452 .setup = exynos4_local_timer_setup,
453 .stop = exynos4_local_timer_stop,
457 static void __init exynos4_timer_resources(
void)
464 #ifdef CONFIG_LOCAL_TIMERS
469 exynos4_mct_tick_isr,
"MCT",
471 WARN(err,
"MCT: can't request IRQ %d (%d)\n",
475 local_timer_register(&exynos4_mct_tick_ops);
479 static void __init exynos4_timer_init(
void)
486 exynos4_timer_resources();
487 exynos4_clocksource_init();
488 exynos4_clockevent_init();
492 .init = exynos4_timer_init,