X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=arch%2Farm%2Fmach-pxa%2Ftime.c;h=ee2beb400414653cdba4166df543633c62ca83b3;hb=35108fb9b3f291b594a8019cb9188da6be2f7990;hp=3ac268fa419b68ce81c04af8e5b369d7f1aae1ca;hpb=12cbbd95e12e911b43afae7f6f4850f616223642;p=linux-2.6 diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 3ac268fa41..ee2beb4004 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -48,27 +49,6 @@ static int pxa_set_rtc(void) return 0; } -/* IRQs are disabled before entering here from do_gettimeofday() */ -static unsigned long pxa_gettimeoffset (void) -{ - long ticks_to_match, elapsed, usec; - - /* Get ticks before next timer match */ - ticks_to_match = OSMR0 - OSCR; - - /* We need elapsed ticks since last match */ - elapsed = LATCH - ticks_to_match; - - /* don't get fooled by the workaround in pxa_timer_interrupt() */ - if (elapsed <= 0) - return 0; - - /* Now convert them to usec */ - usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; - - return usec; -} - #ifdef CONFIG_NO_IDLE_HZ static unsigned long initial_match; static int match_posponed; @@ -121,9 +101,24 @@ static struct irqaction pxa_timer_irq = { .handler = pxa_timer_interrupt, }; +static cycle_t pxa_get_cycles(void) +{ + return OSCR; +} + +static struct clocksource clocksource_pxa = { + .name = "pxa_timer", + .rating = 200, + .read = pxa_get_cycles, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .is_continuous = 1, +}; + static void __init pxa_timer_init(void) { struct timespec tv; + unsigned long flags; set_rtc = pxa_set_rtc; @@ -132,12 +127,20 @@ static void __init pxa_timer_init(void) do_settimeofday(&tv); OIER = 0; /* disable any timer interrupts */ - OSCR = LATCH*2; /* push OSCR out of the way */ - OSMR0 = LATCH; /* set initial match */ OSSR = 0xf; /* clear status on all timers */ setup_irq(IRQ_OST0, &pxa_timer_irq); + local_irq_save(flags); OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ - OSCR = 0; /* initialize free-running timer */ + OSMR0 = OSCR + LATCH; /* set initial match */ + local_irq_restore(flags); + + /* + * OSCR runs continuously on PXA and is not written to, + * so we can use it as clock source directly. + */ + clocksource_pxa.mult = + clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift); + clocksource_register(&clocksource_pxa); } #ifdef CONFIG_NO_IDLE_HZ @@ -210,7 +213,6 @@ struct sys_timer pxa_timer = { .init = pxa_timer_init, .suspend = pxa_timer_suspend, .resume = pxa_timer_resume, - .offset = pxa_gettimeoffset, #ifdef CONFIG_NO_IDLE_HZ .dyn_tick = &pxa_dyn_tick, #endif