diff options
author | Paul Walmsley <paul@pwsan.com> | 2009-04-23 21:11:10 -0600 |
---|---|---|
committer | paul <paul@twilight.(none)> | 2009-04-23 21:11:10 -0600 |
commit | f248076c0dad45b7e50f27096e1aac6a617665db (patch) | |
tree | e787e0dbba967d09a5b05a2088addb8c2459870a /arch/arm/plat-omap/dmtimer.c | |
parent | 219c5b98d5eb86c75abc716087f494fe06c6b64e (diff) |
OMAP2/3 GPTIMER: allow system tick GPTIMER to be changed in board-*.c files
Add a function omap2_gp_clockevent_set_gptimer() for board-*.c files
to use in .init_irq functions to configure the system tick GPTIMER.
Practical choices at this point are GPTIMER1 or GPTIMER12. Both of
these timers are in the WKUP powerdomain, and so are unaffected by
chip power management. GPTIMER1 can use sys_clk as a source, for
applications where a high-resolution timer is more important than
power management. GPTIMER12 has the special property that it has the
secure 32kHz oscillator as its source clock, which may be less prone
to glitches than the off-chip 32kHz oscillator. But on HS devices, it
may not be available for Linux use.
It appears that most boards are fine with GPTIMER1, but BeagleBoard
should use GPTIMER12 when using a 32KiHz timer source, due to hardware bugs
in revisions B4 and below. Modify board-omap3beagle.c to use GPTIMER12.
This patch originally used a Kbuild config option to select the GPTIMER,
but was changed to allow this to be specified in board-*.c files, per
Tony's request.
Kalle Vallo <kalle.valo@nokia.com> found a bug in an earlier version of
this patch - thanks Kalle.
Tested on Beagle rev B4 ES2.1, with and without CONFIG_OMAP_32K_TIMER, and
3430SDP.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Cc: Kalle Valo <kalle.valo@nokia.com>
Diffstat (limited to 'arch/arm/plat-omap/dmtimer.c')
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index a05205c12f7b..55bb99631292 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -509,7 +509,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop); #ifdef CONFIG_ARCH_OMAP1 -void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) +int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) { int n = (timer - dm_timers) << 1; u32 l; @@ -517,23 +517,31 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); l |= source << n; omap_writel(l, MOD_CONF_CTRL_1); + + return 0; } EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); #else -void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) +int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) { + int ret = -EINVAL; + if (source < 0 || source >= 3) - return; + return -EINVAL; clk_disable(timer->fclk); - clk_set_parent(timer->fclk, dm_source_clocks[source]); + ret = clk_set_parent(timer->fclk, dm_source_clocks[source]); clk_enable(timer->fclk); - /* When the functional clock disappears, too quick writes seem to - * cause an abort. */ + /* + * When the functional clock disappears, too quick writes seem + * to cause an abort. XXX Is this still necessary? + */ __delay(150000); + + return ret; } EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); |