ARM: Add HRT clockevent support for IXP4xx platform Signed-off-by: Milan Svoboda Signed-off-by: Kevin Hilman Index: ixp4xx/arch/arm/mach-ixp4xx/common.c =================================================================== --- ixp4xx.orig/arch/arm/mach-ixp4xx/common.c +++ ixp4xx/arch/arm/mach-ixp4xx/common.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -256,15 +257,31 @@ void __init ixp4xx_init_irq(void) static unsigned volatile last_jiffy_time; -#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) +#ifdef CONFIG_HIGH_RES_TIMERS +static void ixp4xx_set_next_event(unsigned long evt, void *priv) +{ + *IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; +} + +static struct clock_event clockevent_ixp4xx = { + .name = "OSTS clock event interface", + .capabilities = CLOCK_CAP_NEXTEVT | CLOCK_HAS_IRQHANDLER, + .shift = 32, + .set_next_event = ixp4xx_set_next_event, +}; +#endif static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - write_seqlock(&xtime_lock); - /* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; +#ifdef CONFIG_HIGH_RES_TIMERS + if (clockevent_ixp4xx.event_handler) + clockevent_ixp4xx.event_handler(regs, NULL); +#endif + write_seqlock(&xtime_lock); + /* * Catch up with the real idea of time */ @@ -404,7 +421,7 @@ static struct clocksource clocksource_ix .rating = 200, .read = ixp4xx_get_cycles, .mask = 0xFFFFFFFF, - .shift = 10, + .shift = 20, .is_continuous = 1, }; @@ -419,5 +436,19 @@ static int __init ixp4xx_clocksource_ini return 0; } - device_initcall(ixp4xx_clocksource_init); + +#ifdef CONFIG_HIGH_RES_TIMERS +static int __init ixp4xx_clockevent_init(void) +{ + clockevent_ixp4xx.mult = div_sc32(FREQ, NSEC_PER_SEC); + clockevent_ixp4xx.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx); + clockevent_ixp4xx.min_delta_ns = + clockevent_delta2ns(0xf, &clockevent_ixp4xx); + setup_local_clockevent(&clockevent_ixp4xx, CPU_MASK_NONE); + + return 0; +} +device_initcall(ixp4xx_clockevent_init); +#endif