aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-integrator/core.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-06-29 10:15:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-06-29 10:15:54 -0400
commitb720f73296916e87c744193c57bc8687d35888fe (patch)
tree0fba1e98b336929a8f8c4d20d6a82714b7106c98 /arch/arm/mach-integrator/core.c
parent6904b2465cf30265a67711025815784aa345bfad (diff)
[PATCH] ARM: Convert ARM timer implementations to use readl/writel
Convert ARMs timer implementations to use readl/writel instead of accessing the registers via a struct. People have recently asked if accessing timers via a structure is the "right way" and its not the Linux way. So fix this code to conform to "The Linux Way"(tm). Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/mach-integrator/core.c')
-rw-r--r--arch/arm/mach-integrator/core.c42
1 files changed, 14 insertions, 28 deletions
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 9222e57bd872..797c7fddaa0d 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -20,6 +20,7 @@
20#include <asm/irq.h> 20#include <asm/irq.h>
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/hardware/amba.h> 22#include <asm/hardware/amba.h>
23#include <asm/hardware/arm_timer.h>
23#include <asm/arch/cm.h> 24#include <asm/arch/cm.h>
24#include <asm/system.h> 25#include <asm/system.h>
25#include <asm/leds.h> 26#include <asm/leds.h>
@@ -156,16 +157,6 @@ EXPORT_SYMBOL(cm_control);
156#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) 157#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
157#endif 158#endif
158 159
159/*
160 * What does it look like?
161 */
162typedef struct TimerStruct {
163 unsigned long TimerLoad;
164 unsigned long TimerValue;
165 unsigned long TimerControl;
166 unsigned long TimerClear;
167} TimerStruct_t;
168
169static unsigned long timer_reload; 160static unsigned long timer_reload;
170 161
171/* 162/*
@@ -174,7 +165,6 @@ static unsigned long timer_reload;
174 */ 165 */
175unsigned long integrator_gettimeoffset(void) 166unsigned long integrator_gettimeoffset(void)
176{ 167{
177 volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
178 unsigned long ticks1, ticks2, status; 168 unsigned long ticks1, ticks2, status;
179 169
180 /* 170 /*
@@ -183,11 +173,11 @@ unsigned long integrator_gettimeoffset(void)
183 * an interrupt. We get around this by ensuring that the 173 * an interrupt. We get around this by ensuring that the
184 * counter has not reloaded between our two reads. 174 * counter has not reloaded between our two reads.
185 */ 175 */
186 ticks2 = timer1->TimerValue & 0xffff; 176 ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
187 do { 177 do {
188 ticks1 = ticks2; 178 ticks1 = ticks2;
189 status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); 179 status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
190 ticks2 = timer1->TimerValue & 0xffff; 180 ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
191 } while (ticks2 > ticks1); 181 } while (ticks2 > ticks1);
192 182
193 /* 183 /*
@@ -213,20 +203,19 @@ unsigned long integrator_gettimeoffset(void)
213static irqreturn_t 203static irqreturn_t
214integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 204integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
215{ 205{
216 volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
217
218 write_seqlock(&xtime_lock); 206 write_seqlock(&xtime_lock);
219 207
220 /* 208 /*
221 * clear the interrupt 209 * clear the interrupt
222 */ 210 */
223 timer1->TimerClear = 1; 211 writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
224 212
225 /* 213 /*
226 * the clock tick routines are only processed on the 214 * the clock tick routines are only processed on the
227 * primary CPU 215 * primary CPU
228 */ 216 */
229 if (hard_smp_processor_id() == 0) { 217 if (hard_smp_processor_id() == 0) {
218 nmi_tick();
230 timer_tick(regs); 219 timer_tick(regs);
231#ifdef CONFIG_SMP 220#ifdef CONFIG_SMP
232 smp_send_timer(); 221 smp_send_timer();
@@ -256,32 +245,29 @@ static struct irqaction integrator_timer_irq = {
256 */ 245 */
257void __init integrator_time_init(unsigned long reload, unsigned int ctrl) 246void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
258{ 247{
259 volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; 248 unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
260 volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
261 volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
262 unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */
263 249
264 timer_reload = reload; 250 timer_reload = reload;
265 timer_ctrl |= ctrl; 251 timer_ctrl |= ctrl;
266 252
267 if (timer_reload > 0x100000) { 253 if (timer_reload > 0x100000) {
268 timer_reload >>= 8; 254 timer_reload >>= 8;
269 timer_ctrl |= 0x08; /* /256 */ 255 timer_ctrl |= TIMER_CTRL_DIV256;
270 } else if (timer_reload > 0x010000) { 256 } else if (timer_reload > 0x010000) {
271 timer_reload >>= 4; 257 timer_reload >>= 4;
272 timer_ctrl |= 0x04; /* /16 */ 258 timer_ctrl |= TIMER_CTRL_DIV16;
273 } 259 }
274 260
275 /* 261 /*
276 * Initialise to a known state (all timers off) 262 * Initialise to a known state (all timers off)
277 */ 263 */
278 timer0->TimerControl = 0; 264 writel(0, TIMER0_VA_BASE + TIMER_CTRL);
279 timer1->TimerControl = 0; 265 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
280 timer2->TimerControl = 0; 266 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
281 267
282 timer1->TimerLoad = timer_reload; 268 writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD);
283 timer1->TimerValue = timer_reload; 269 writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE);
284 timer1->TimerControl = timer_ctrl; 270 writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL);
285 271
286 /* 272 /*
287 * Make irqs happen for the system timer 273 * Make irqs happen for the system timer