summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-01-15 19:10:33 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-04-29 19:04:15 +0200
commitb9cedda230793cbf58eb012ddadedd490cc8e129 (patch)
tree5c1e21e04206d68d9089299e6b9f61347c3f8070
parentARM: Improve documentation in arm_timer.h (diff)
downloadlinux-b9cedda230793cbf58eb012ddadedd490cc8e129.tar.xz
linux-b9cedda230793cbf58eb012ddadedd490cc8e129.zip
ARM: Integrator: convert to generic time support
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-integrator/common.h1
-rw-r--r--arch/arm/mach-integrator/core.c62
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c1
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c1
5 files changed, 31 insertions, 35 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c5408bf1bf43..7698d8705a8f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -241,6 +241,7 @@ config ARCH_INTEGRATOR
select HAVE_CLK
select COMMON_CLKDEV
select ICST525
+ select GENERIC_TIME
help
Support for ARM's Integrator platform.
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 609c49de3d47..7dc24bb9bdc1 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,2 +1 @@
extern void integrator_time_init(unsigned long, unsigned int);
-extern unsigned long integrator_gettimeoffset(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 096f899625f8..87c6f980944d 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -19,6 +19,7 @@
#include <linux/termios.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
+#include <linux/clocksource.h>
#include <linux/io.h>
#include <asm/clkdev.h>
@@ -225,7 +226,6 @@ EXPORT_SYMBOL(cm_control);
#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000)
#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100)
#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200)
-#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
/*
* How long is the timer interval?
@@ -241,42 +241,38 @@ EXPORT_SYMBOL(cm_control);
static unsigned long timer_reload;
-/*
- * Returns number of ms since last clock interrupt. Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-unsigned long integrator_gettimeoffset(void)
+static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE;
+
+static cycle_t timersp_read(struct clocksource *cs)
{
- unsigned long ticks1, ticks2, status;
+ return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff);
+}
- /*
- * Get the current number of ticks. Note that there is a race
- * condition between us reading the timer and checking for
- * an interrupt. We get around this by ensuring that the
- * counter has not reloaded between our two reads.
- */
- ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
- do {
- ticks1 = ticks2;
- status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
- ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
- } while (ticks2 > ticks1);
+static struct clocksource clocksource_timersp = {
+ .name = "timer2",
+ .rating = 200,
+ .read = timersp_read,
+ .mask = CLOCKSOURCE_MASK(16),
+ .shift = 16,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
- /*
- * Number of ticks since last interrupt.
- */
- ticks1 = timer_reload - ticks2;
+static void integrator_clocksource_init(u32 khz)
+{
+ struct clocksource *cs = &clocksource_timersp;
+ void __iomem *base = clksrc_base;
+ u32 ctrl = TIMER_CTRL_ENABLE;
- /*
- * Interrupt pending? If so, we've reloaded once already.
- */
- if (status & (1 << IRQ_TIMERINT1))
- ticks1 += timer_reload;
+ if (khz >= 1500) {
+ khz /= 16;
+ ctrl = TIMER_CTRL_DIV16;
+ }
- /*
- * Convert the ticks to usecs
- */
- return TICKS2USECS(ticks1);
+ writel(ctrl, base + TIMER_CTRL);
+ writel(0xffff, base + TIMER_LOAD);
+
+ cs->mult = clocksource_khz2mult(khz, cs->shift);
+ clocksource_register(cs);
}
/*
@@ -308,6 +304,8 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
{
unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
+ integrator_clocksource_init(reload * HZ / 1000);
+
timer_reload = reload;
timer_ctrl |= ctrl;
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 018c32da4c86..cfb718fe31a8 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -342,7 +342,6 @@ static void __init ap_init_timer(void)
static struct sys_timer ap_timer = {
.init = ap_init_timer,
- .offset = integrator_gettimeoffset,
};
MACHINE_START(INTEGRATOR, "ARM-Integrator")
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index c66e8fa0e622..3e84732163ea 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -577,7 +577,6 @@ static void __init intcp_timer_init(void)
static struct sys_timer cp_timer = {
.init = intcp_timer_init,
- .offset = integrator_gettimeoffset,
};
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")