diff options
Diffstat (limited to 'arch/arm/mach-exynos/mct.c')
-rw-r--r-- | arch/arm/mach-exynos/mct.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c index 85b5527d091..cae3e2dae2e 100644 --- a/arch/arm/mach-exynos/mct.c +++ b/arch/arm/mach-exynos/mct.c @@ -29,12 +29,13 @@ #include <mach/regs-mct.h> #include <asm/mach/time.h> +#define TICK_BASE_CNT 1 + enum { MCT_INT_SPI, MCT_INT_PPI }; -static unsigned long clk_cnt_per_tick; static unsigned long clk_rate; static unsigned int mct_int_type; @@ -205,11 +206,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles, static void exynos4_comp_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { + unsigned long cycles_per_jiffy; exynos4_mct_comp0_stop(); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - exynos4_mct_comp0_start(mode, clk_cnt_per_tick); + cycles_per_jiffy = + (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); + exynos4_mct_comp0_start(mode, cycles_per_jiffy); break; case CLOCK_EVT_MODE_ONESHOT: @@ -248,9 +252,7 @@ static struct irqaction mct_comp_event_irq = { static void exynos4_clockevent_init(void) { - clk_cnt_per_tick = clk_rate / 2 / HZ; - - clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5); + clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5); mct_comp_device.max_delta_ns = clockevent_delta2ns(0xffffffff, &mct_comp_device); mct_comp_device.min_delta_ns = @@ -258,7 +260,10 @@ static void exynos4_clockevent_init(void) mct_comp_device.cpumask = cpumask_of(0); clockevents_register_device(&mct_comp_device); - setup_irq(IRQ_MCT_G0, &mct_comp_event_irq); + if (soc_is_exynos5250()) + setup_irq(EXYNOS5_IRQ_MCT_G0, &mct_comp_event_irq); + else + setup_irq(EXYNOS4_IRQ_MCT_G0, &mct_comp_event_irq); } #ifdef CONFIG_LOCAL_TIMERS @@ -314,12 +319,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); + unsigned long cycles_per_jiffy; exynos4_mct_tick_stop(mevt); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - exynos4_mct_tick_start(clk_cnt_per_tick, mevt); + cycles_per_jiffy = + (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); + exynos4_mct_tick_start(cycles_per_jiffy, mevt); break; case CLOCK_EVT_MODE_ONESHOT: @@ -393,7 +401,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; evt->rating = 450; - clockevents_calc_mult_shift(evt, clk_rate / 2, 5); + clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5); evt->max_delta_ns = clockevent_delta2ns(0x7fffffff, evt); evt->min_delta_ns = @@ -401,21 +409,21 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) clockevents_register_device(evt); - exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET); + exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); if (mct_int_type == MCT_INT_SPI) { if (cpu == 0) { mct_tick0_event_irq.dev_id = mevt; - evt->irq = IRQ_MCT_L0; - setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq); + evt->irq = EXYNOS4_IRQ_MCT_L0; + setup_irq(EXYNOS4_IRQ_MCT_L0, &mct_tick0_event_irq); } else { mct_tick1_event_irq.dev_id = mevt; - evt->irq = IRQ_MCT_L1; - setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); - irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); + evt->irq = EXYNOS4_IRQ_MCT_L1; + setup_irq(EXYNOS4_IRQ_MCT_L1, &mct_tick1_event_irq); + irq_set_affinity(EXYNOS4_IRQ_MCT_L1, cpumask_of(1)); } } else { - enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0); + enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0); } } @@ -437,7 +445,7 @@ void local_timer_stop(struct clock_event_device *evt) else remove_irq(evt->irq, &mct_tick1_event_irq); else - disable_percpu_irq(IRQ_MCT_LOCALTIMER); + disable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER); } #endif /* CONFIG_LOCAL_TIMERS */ @@ -452,11 +460,11 @@ static void __init exynos4_timer_resources(void) if (mct_int_type == MCT_INT_PPI) { int err; - err = request_percpu_irq(IRQ_MCT_LOCALTIMER, + err = request_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, exynos4_mct_tick_isr, "MCT", &percpu_mct_tick); WARN(err, "MCT: can't request IRQ %d (%d)\n", - IRQ_MCT_LOCALTIMER, err); + EXYNOS_IRQ_MCT_LOCALTIMER, err); } #endif /* CONFIG_LOCAL_TIMERS */ } |