Define a clocksource for the at91rm9200, switching it to use GENERIC_TIME. (No clockevent support; this is against 2.6.20-rc code.)
Also, slightly streamline reads of the 32KHz counter; if we hit the update window, we can now use 3 reads not 4. Signed-off-by: David Brownell <[EMAIL PROTECTED]> --- We've been asked to forward stuff to LKML not ARM or RT lists, so ... arch/arm/mach-at91rm9200/Kconfig | 1 arch/arm/mach-at91rm9200/at91rm9200_time.c | 47 ++++++++++++++++------------- 2 files changed, 28 insertions(+), 20 deletions(-) NOTE: at91sam926x chips need other solutions. The sam9263 will have two RTTs; one could work like this 32K timer and the other can be the system's battery-backed RTC. Otherwise the best bet may be the counter/timer module, currently not usable from mainstream Linux patchsets. If the board doesn't need one module for external interfacing, two 16-bit timers can chain to be a clocksource (I have example code) and the third could issue clockevents with the same precision (base is multi-MHz vs 32K). Index: at91/arch/arm/mach-at91rm9200/Kconfig =================================================================== --- at91.orig/arch/arm/mach-at91rm9200/Kconfig 2006-12-26 12:15:56.000000000 -0800 +++ at91/arch/arm/mach-at91rm9200/Kconfig 2006-12-26 12:16:04.000000000 -0800 @@ -7,6 +7,7 @@ choice config ARCH_AT91RM9200 bool "AT91RM9200" + select GENERIC_TIME config ARCH_AT91SAM9260 bool "AT91SAM9260" Index: at91/arch/arm/mach-at91rm9200/at91rm9200_time.c =================================================================== --- at91.orig/arch/arm/mach-at91rm9200/at91rm9200_time.c 2006-12-26 12:07:36.000000000 -0800 +++ at91/arch/arm/mach-at91rm9200/at91rm9200_time.c 2006-12-26 12:16:04.000000000 -0800 @@ -25,6 +25,7 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/time.h> +#include <linux/clocksource.h> #include <asm/hardware.h> #include <asm/io.h> @@ -38,33 +39,22 @@ static unsigned long last_crtr; * The ST_CRTR is updated asynchronously to the master clock. It is therefore * necessary to read it twice (with the same value) to ensure accuracy. */ -static inline unsigned long read_CRTR(void) { +static inline unsigned long read_CRTR(void) +{ unsigned long x1, x2; - do { - x1 = at91_sys_read(AT91_ST_CRTR); + x1 = at91_sys_read(AT91_ST_CRTR); + for (;;) { x2 = at91_sys_read(AT91_ST_CRTR); - } while (x1 != x2); + if (x1 == x2) + break; + x1 = x2; + }; return x1; } /* - * Returns number of microseconds since last timer interrupt. Note that interrupts - * will have been disabled by do_gettimeofday() - * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. - * 'tick' is usecs per jiffy (linux/timex.h). - */ -static unsigned long at91rm9200_gettimeoffset(void) -{ - unsigned long elapsed; - - elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV; - - return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; -} - -/* * IRQ handler for the timer. */ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) @@ -91,6 +81,20 @@ static struct irqaction at91rm9200_timer .handler = at91rm9200_timer_interrupt }; +static cycle_t read_clk32k(void) +{ + return read_CRTR(); +} + +static struct clocksource clk32k = { + .name = "32k_counter", + .rating = 200, + .read = read_clk32k, + .mask = CLOCKSOURCE_MASK(20), + .shift = 10, + .is_continuous = 1, +}; + void at91rm9200_timer_reset(void) { last_crtr = 0; @@ -125,6 +129,10 @@ void __init at91rm9200_timer_init(void) /* Initialize and enable the timer interrupt */ at91rm9200_timer_reset(); + + /* register clocksource */ + clk32k.mult = clocksource_hz2mult(32768, clk32k.shift); + clocksource_register(&clk32k); } #ifdef CONFIG_PM @@ -139,7 +147,6 @@ static void at91rm9200_timer_suspend(voi struct sys_timer at91rm9200_timer = { .init = at91rm9200_timer_init, - .offset = at91rm9200_gettimeoffset, .suspend = at91rm9200_timer_suspend, .resume = at91rm9200_timer_reset, }; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/