ARM: OMAP: Add clocksource driver for OMAP
Subsystems (3)
PATCH 3/4 ARM: OMAP: Add clocksource driver for OMAP
ARM: OMAP: Add clocksource driver for OMAP.
This is an update of
http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3876/1
from Daniel Walker and Kevin Hilman.
Changes from Dirk Behme:
- Apply cleanly to recent kernel (pt_regs change)
- Move clocksource init to extra function. Can be called later by clocksource subsystem
- Remove warning: 'omap_32k_timer_handler' defined but
not used
when CONFIG_NO_IDLE_HZ isn't set.
- Minor cleanups
Changes from David Brownell:
- OMAP1, OMAP2: 32k clocksource is always available on
16xx and 24xx
- OMAP1 MPU timer:
* consult clock framework to determine xtal clock
* bugfix sched_clock() low order bits
* cleanup
- Kconfig updates
Note that "MPU timer" still doesn't have lost tick support.
arch/arm/Kconfig +1 -0
@@ -340,6 +340,7 @@ config ARCH_LH7A40X config ARCH_OMAP bool "TI OMAP" + select GENERIC_TIME help Support for TI's OMAP platform (OMAP1 and OMAP2).
arch/arm/plat-omap/common.c +50 -0
53 lines not on this page · raw message
arch/arm/plat-omap/timer32k.c +18 -16
@@ -42,6 +42,7 @@#include <linux/spinlock.h> #include <linux/err.h> #include <linux/clk.h> +#include <linux/clocksource.h> #include <asm/system.h> #include <asm/hardware.h>
@@ -171,15 +172,6 @@ omap_32k_ticks_to_nsecs(unsigned long tistatic unsigned long omap_32k_last_tick =0 ;/* -* Returns elapsed usecs since last 32k timer interrupt -*/ -static unsigned long omap_32k_timer_gettimeoffset (void ) -{ -unsigned long now =omap_32k_sync_timer_read (); -return omap_32k_ticks_to_usecs (now - omap_32k_last_tick); -} - -/* * Returns current time from boot in nsecs. It's OK for this to wrap * around for now, as it's just a relative time stamp. */
@@ -217,11 +209,6 @@ static inline irqreturn_t _omap_32k_timereturn IRQ_HANDLED ; } -static irqreturn_t omap_32k_timer_handler (int irq,void *dev_id) -{ -return _omap_32k_timer_interrupt (irq, dev_id); -} -static irqreturn_t omap_32k_timer_interrupt (int irq,void *dev_id) {unsigned long flags;
@@ -234,6 +221,7 @@ static irqreturn_t omap_32k_timer_interr }#ifdef CONFIG_NO_IDLE_HZ +/* * Programs the next timer interrupt needed. Called when dynamic tick is * enabled, and to reprogram the ticks to skip from pm_idle. Note that
@@ -269,6 +257,22 @@ static int omap_32k_timer_disable_dyn_tireturn 0 ; } +static irqreturn_t omap_32k_timer_handler (int irq,void *dev_id) +{ +unsigned long now; + + now =omap_32k_sync_timer_read (); + +/* Don't bother reprogramming timer if last tick was before next +* jiffie. We will get another interrupt when previously programmed +* timer expires. This cuts down interrupt load quite a bit. +*/ +if (now - omap_32k_last_tick <OMAP_32K_TICKS_PER_HZ ) +return IRQ_HANDLED ; + +return _omap_32k_timer_interrupt (irq, dev_id); +} +static struct dyn_tick_timer omap_dyn_tick_timer = { .enable = omap_32k_timer_enable_dyn_tick, .disable = omap_32k_timer_disable_dyn_tick,
@@ -291,7 +295,6 @@ static __init void omap_init_32k_timer(vif (cpu_class_is_omap1 ())setup_irq (INT_OS_TIMER , &omap_32k_timer_irq); - omap_timer.offset = omap_32k_timer_gettimeoffset; omap_32k_last_tick =omap_32k_sync_timer_read ();#ifdef CONFIG_ARCH_OMAP2
@@ -326,5 +329,4 @@ static void __init omap_timer_init(void)struct sys_timer omap_timer = { .init = omap_timer_init, - .offset =NULL ,/* Initialized later */ };
arch/arm/mach-omap1/time.c +71 -71
208 lines not on this page · raw message