diff options
Diffstat (limited to 'arch/arm/mach-omap1/time.c')
| -rw-r--r-- | arch/arm/mach-omap1/time.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index d540539c9bbb..191a9b1ee9b7 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c | |||
| @@ -247,13 +247,6 @@ unsigned long long sched_clock(void) | |||
| 247 | #define OMAP_32K_TIMER_TCR 0x04 | 247 | #define OMAP_32K_TIMER_TCR 0x04 |
| 248 | 248 | ||
| 249 | #define OMAP_32K_TICKS_PER_HZ (32768 / HZ) | 249 | #define OMAP_32K_TICKS_PER_HZ (32768 / HZ) |
| 250 | #if (32768 % HZ) != 0 | ||
| 251 | /* We cannot ignore modulo. | ||
| 252 | * Potential error can be as high as several percent. | ||
| 253 | */ | ||
| 254 | #define OMAP_32K_TICK_MODULO (32768 % HZ) | ||
| 255 | static unsigned modulo_count = 0; /* Counts 1/HZ units */ | ||
| 256 | #endif | ||
| 257 | 250 | ||
| 258 | /* | 251 | /* |
| 259 | * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 | 252 | * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 |
| @@ -296,13 +289,22 @@ static inline void omap_32k_timer_stop(void) | |||
| 296 | } | 289 | } |
| 297 | 290 | ||
| 298 | /* | 291 | /* |
| 299 | * Rounds down to nearest usec | 292 | * Rounds down to nearest usec. Note that this will overflow for larger values. |
| 300 | */ | 293 | */ |
| 301 | static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) | 294 | static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) |
| 302 | { | 295 | { |
| 303 | return (ticks_32k * 5*5*5*5*5*5) >> 9; | 296 | return (ticks_32k * 5*5*5*5*5*5) >> 9; |
| 304 | } | 297 | } |
| 305 | 298 | ||
| 299 | /* | ||
| 300 | * Rounds down to nearest nsec. | ||
| 301 | */ | ||
| 302 | static inline unsigned long long | ||
| 303 | omap_32k_ticks_to_nsecs(unsigned long ticks_32k) | ||
| 304 | { | ||
| 305 | return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; | ||
| 306 | } | ||
| 307 | |||
| 306 | static unsigned long omap_32k_last_tick = 0; | 308 | static unsigned long omap_32k_last_tick = 0; |
| 307 | 309 | ||
| 308 | /* | 310 | /* |
| @@ -315,6 +317,15 @@ static unsigned long omap_32k_timer_gettimeoffset(void) | |||
| 315 | } | 317 | } |
| 316 | 318 | ||
| 317 | /* | 319 | /* |
| 320 | * Returns current time from boot in nsecs. It's OK for this to wrap | ||
| 321 | * around for now, as it's just a relative time stamp. | ||
| 322 | */ | ||
| 323 | unsigned long long sched_clock(void) | ||
| 324 | { | ||
| 325 | return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); | ||
| 326 | } | ||
| 327 | |||
| 328 | /* | ||
| 318 | * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this | 329 | * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this |
| 319 | * function is also called from other interrupts to remove latency | 330 | * function is also called from other interrupts to remove latency |
| 320 | * issues with dynamic tick. In the dynamic tick case, we need to lock | 331 | * issues with dynamic tick. In the dynamic tick case, we need to lock |
| @@ -330,19 +341,6 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | |||
| 330 | now = omap_32k_sync_timer_read(); | 341 | now = omap_32k_sync_timer_read(); |
| 331 | 342 | ||
| 332 | while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { | 343 | while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { |
| 333 | #ifdef OMAP_32K_TICK_MODULO | ||
| 334 | /* Modulo addition may put omap_32k_last_tick ahead of now | ||
| 335 | * and cause unwanted repetition of the while loop. | ||
| 336 | */ | ||
| 337 | if (unlikely(now - omap_32k_last_tick == ~0)) | ||
| 338 | break; | ||
| 339 | |||
| 340 | modulo_count += OMAP_32K_TICK_MODULO; | ||
| 341 | if (modulo_count > HZ) { | ||
| 342 | ++omap_32k_last_tick; | ||
| 343 | modulo_count -= HZ; | ||
| 344 | } | ||
| 345 | #endif | ||
| 346 | omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; | 344 | omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; |
| 347 | timer_tick(regs); | 345 | timer_tick(regs); |
| 348 | } | 346 | } |
