diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-28 14:40:39 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-28 14:40:39 -0700 |
commit | ebdea46fecae40c4d7effcd33f40918a37a1df4b (patch) | |
tree | e4312bf7f1f3d184738963a0ec300aa9fdfd55c1 /arch/arm/plat-omap/timer32k.c | |
parent | fecf3404f4aba6d0edeba31eeb018cbb6326dff2 (diff) | |
parent | 250d375d1da45a5e08ab8baf5eaa7eb258afd82b (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (130 commits)
[ARM] 3856/1: Add clocksource for Intel IXP4xx platforms
[ARM] 3855/1: Add generic time support
[ARM] 3873/1: S3C24XX: Add irq_chip names
[ARM] 3872/1: S3C24XX: Apply consistant tabbing to irq_chips
[ARM] 3871/1: S3C24XX: Fix ordering of EINT4..23
[ARM] nommu: confirms the CR_V bit in nommu mode
[ARM] nommu: abort handler fixup for !CPU_CP15_MMU cores.
[ARM] 3870/1: AT91: Start removing static memory mappings
[ARM] 3869/1: AT91: NAND support for DK and KB9202 boards
[ARM] 3868/1: AT91 hardware header update
[ARM] 3867/1: AT91 GPIO update
[ARM] 3866/1: AT91 clock update
[ARM] 3865/1: AT91RM9200 header updates
[ARM] 3862/2: S3C2410 - add basic power management support for AML M5900 series
[ARM] kthread: switch arch/arm/kernel/apm.c
[ARM] Off-by-one in arch/arm/common/icst*
[ARM] 3864/1: Refactore sharpsl_pm
[ARM] 3863/1: Add Locomo SPI Device
[ARM] 3847/2: Convert LOMOMO to use struct device for GPIOs
[ARM] Use CPU_CACHE_* where possible in asm/cacheflush.h
...
Diffstat (limited to 'arch/arm/plat-omap/timer32k.c')
-rw-r--r-- | arch/arm/plat-omap/timer32k.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c index 281ecc7fcdf..cf6df3378d3 100644 --- a/arch/arm/plat-omap/timer32k.c +++ b/arch/arm/plat-omap/timer32k.c @@ -105,6 +105,8 @@ static inline unsigned long omap_32k_timer_read(int reg) static inline void omap_32k_timer_start(unsigned long load_val) { + if (!load_val) + load_val = 1; omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); } @@ -192,14 +194,11 @@ unsigned long long sched_clock(void) * issues with dynamic tick. In the dynamic tick case, we need to lock * with irqsave. */ -static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - unsigned long flags; unsigned long now; - write_seqlock_irqsave(&xtime_lock, flags); - omap_32k_timer_ack_irq(); now = omap_32k_sync_timer_read(); @@ -215,6 +214,23 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, * continuous timer can be overridden from pm_idle to be longer. */ omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); + + return IRQ_HANDLED; +} + +static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id, + struct pt_regs *regs) +{ + return _omap_32k_timer_interrupt(irq, dev_id, regs); +} + +static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long flags; + + write_seqlock_irqsave(&xtime_lock, flags); + _omap_32k_timer_interrupt(irq, dev_id, regs); write_sequnlock_irqrestore(&xtime_lock, flags); return IRQ_HANDLED; @@ -230,7 +246,15 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, */ void omap_32k_timer_reprogram(unsigned long next_tick) { - omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); + unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1; + unsigned long now = omap_32k_sync_timer_read(); + unsigned long idled = now - omap_32k_last_tick; + + if (idled + 1 < ticks) + ticks -= idled; + else + ticks = 1; + omap_32k_timer_start(ticks); } static struct irqaction omap_32k_timer_irq; @@ -252,7 +276,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = { .enable = omap_32k_timer_enable_dyn_tick, .disable = omap_32k_timer_disable_dyn_tick, .reprogram = omap_32k_timer_reprogram, - .handler = omap_32k_timer_interrupt, + .handler = omap_32k_timer_handler, }; #endif /* CONFIG_NO_IDLE_HZ */ |