ARM: OMAP: Add clockevent driver for OMAP
Subsystems (3)
PATCH 4/4 ARM: OMAP: Add clockevent driver for OMAP
Add clockevent driver for OMAP.
This is an update of the initial patch from Daniel Walker and Kevin Hilman. Update to apply cleanly to 2.6.20-rc1 by Dirk Behme.
Signed-off-by Dirk Behme <dirk.behme_at_gmail.com>
arch/arm/mach-omap1/time.c +64 -8
@@ -42,6 +42,7 @@#include <linux/clk.h> #include <linux/err.h> #include <linux/clocksource.h> +#include <linux/clockchips.h> #include <asm/system.h> #include <asm/hardware.h>
@@ -102,15 +103,33 @@ static inline unsigned long omap_mpu_timreturn timer->read_tim; } -static inline void omap_mpu_timer_start (int nr,unsigned long load_val) +static inline void omap_mpu_set_autoreset (int nr) +{ +volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); + + timer->cntl = timer->cntl |MPU_TIMER_AR ; +} + +static inline void omap_mpu_remove_autoreset (int nr) {volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); + timer->cntl = timer->cntl & ~MPU_TIMER_AR ; +} + +static inline void omap_mpu_timer_start (int nr,unsigned long load_val, +int autoreset) +{ +volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); +unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE |MPU_TIMER_ST ); + +if (autoreset) timerflags |=MPU_TIMER_AR ; + timer->cntl =MPU_TIMER_CLOCK_ENABLE ;udelay (1 ); timer->load_tim = load_val;udelay (1 ); - timer->cntl = (MPU_TIMER_CLOCK_ENABLE |MPU_TIMER_AR |MPU_TIMER_ST ); + timer->cntl = timerflags; }/*
@@ -118,12 +137,39 @@ static inline void omap_mpu_timer_start(* MPU timer 1 ... count down to zero, interrupt, reload * --------------------------------------------------------------------------- */ +static void omap_mpu_set_next_event (unsigned long cycles, +struct clock_event_device *evt) +{ +omap_mpu_timer_start (0 , cycles,0 ); +} + +static void omap_mpu_set_mode (enum clock_event_mode mode, +struct clock_event_device *evt) +{ +switch (mode) { +case CLOCK_EVT_PERIODIC : +omap_mpu_set_autoreset (0 ); +break ; +case CLOCK_EVT_ONESHOT : +omap_mpu_remove_autoreset (0 ); +break ; +case CLOCK_EVT_SHUTDOWN : +break ; + } +} + +static struct clock_event_device clockevent_mpu_timer1 = { + .name ="mpu_timer1" , + .capabilities =CLOCK_CAP_NEXTEVT |CLOCK_CAP_TICK | +CLOCK_CAP_UPDATE , + .shift =32 , + .set_next_event = omap_mpu_set_next_event, + .set_mode = omap_mpu_set_mode, +}; +static irqreturn_t omap_mpu_timer1_interrupt (int irq,void *dev_id) { -write_seqlock (&xtime_lock); -/* NOTE: no lost-tick detection/handling! */ -timer_tick (); -write_sequnlock (&xtime_lock); + clockevent_mpu_timer1.event_handler ();return IRQ_HANDLED ; }
@@ -139,9 +185,19 @@ static __init void omap_init_mpu_timer(uset_cyc2ns_scale (rate /1000 );setup_irq (INT_TIMER1 , &omap_mpu_timer1_irq); -omap_mpu_timer_start (0 , (rate /HZ ) -1 ); +omap_mpu_timer_start (0 , (rate /HZ ) -1 ,1 ); + + clockevent_mpu_timer1.mult =div_sc (rate,NSEC_PER_SEC , + clockevent_mpu_timer1.shift); + clockevent_mpu_timer1.max_delta_ns = +clockevent_delta2ns (-1 , &clockevent_mpu_timer1); + clockevent_mpu_timer1.min_delta_ns = +clockevent_delta2ns (1 , &clockevent_mpu_timer1); + +register_global_clockevent (&clockevent_mpu_timer1); } +/* * --------------------------------------------------------------------------- * MPU timer 2 ... free running 32-bit clock source and scheduler clock
@@ -185,7 +241,7 @@ static void __init omap_init_clocksource = clocksource_khz2mult(rate/1000, clocksource_mpu.shift);setup_irq (INT_TIMER2 , &omap_mpu_timer2_irq); -omap_mpu_timer_start (1 , ~0 ); +omap_mpu_timer_start (1 , ~0 ,1 );if (clocksource_register (&clocksource_mpu))printk (err, clocksource_mpu.name);
arch/arm/plat-omap/Kconfig +2 -0
@@ -11,6 +11,8 @@ choice config ARCH_OMAP1 bool "TI OMAP1" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS config ARCH_OMAP2 bool "TI OMAP2"
arch/arm/plat-omap/timer32k.c +58 -100
206 lines not on this page · raw message