diff options
author | Aaro Koskinen <aaro.koskinen@nokia.com> | 2010-04-07 05:57:22 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2010-04-22 20:32:36 -0400 |
commit | 2decb12e3ebec556520dd92178572449af8ed617 (patch) | |
tree | 53eb4aa1479fff629c1b9005ad6b602d0e8e044a /arch/arm/plat-omap/common.c | |
parent | e2bca7c76a79b68506bfc3699beb74c0d41fe230 (diff) |
omap: fix clocksource_32k to start from zero
When the 32k sync timer is used for sched_clock(), it should count
time from the kernel boot (clocksource init) instead of the last HW
reset. Otherwise printk.time values will jump suddenly during the boot:
[ 0.000000] calling omap2_clk_arch_init+0x0/0x138 @ 1
[ 0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned -22 after 0 usecs
[ 0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned with error code -22
[ 0.000000] calling omap_init_clocksource_32k+0x0/0x98 @ 1
[ 508.697937] initcall omap_init_clocksource_32k+0x0/0x98 returned 0 after 0 usecs
[ 508.697967] calling omap_init_devices+0x0/0x38 @ 1
[ 508.698425] initcall omap_init_devices+0x0/0x38 returned 0 after 0 usecs
This will confuse tools such as scripts/bootgraph.pl.
Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap/common.c')
-rw-r--r-- | arch/arm/plat-omap/common.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index 088c1a03b946..01cbb48442ac 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c | |||
@@ -100,10 +100,17 @@ EXPORT_SYMBOL(omap_get_var_config); | |||
100 | 100 | ||
101 | #include <linux/clocksource.h> | 101 | #include <linux/clocksource.h> |
102 | 102 | ||
103 | /* | ||
104 | * offset_32k holds the init time counter value. It is then subtracted | ||
105 | * from every counter read to achieve a counter that counts time from the | ||
106 | * kernel boot (needed for sched_clock()). | ||
107 | */ | ||
108 | static u32 offset_32k __read_mostly; | ||
109 | |||
103 | #ifdef CONFIG_ARCH_OMAP16XX | 110 | #ifdef CONFIG_ARCH_OMAP16XX |
104 | static cycle_t omap16xx_32k_read(struct clocksource *cs) | 111 | static cycle_t omap16xx_32k_read(struct clocksource *cs) |
105 | { | 112 | { |
106 | return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED); | 113 | return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k; |
107 | } | 114 | } |
108 | #else | 115 | #else |
109 | #define omap16xx_32k_read NULL | 116 | #define omap16xx_32k_read NULL |
@@ -112,7 +119,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs) | |||
112 | #ifdef CONFIG_ARCH_OMAP2420 | 119 | #ifdef CONFIG_ARCH_OMAP2420 |
113 | static cycle_t omap2420_32k_read(struct clocksource *cs) | 120 | static cycle_t omap2420_32k_read(struct clocksource *cs) |
114 | { | 121 | { |
115 | return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10); | 122 | return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k; |
116 | } | 123 | } |
117 | #else | 124 | #else |
118 | #define omap2420_32k_read NULL | 125 | #define omap2420_32k_read NULL |
@@ -121,7 +128,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs) | |||
121 | #ifdef CONFIG_ARCH_OMAP2430 | 128 | #ifdef CONFIG_ARCH_OMAP2430 |
122 | static cycle_t omap2430_32k_read(struct clocksource *cs) | 129 | static cycle_t omap2430_32k_read(struct clocksource *cs) |
123 | { | 130 | { |
124 | return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10); | 131 | return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k; |
125 | } | 132 | } |
126 | #else | 133 | #else |
127 | #define omap2430_32k_read NULL | 134 | #define omap2430_32k_read NULL |
@@ -130,7 +137,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs) | |||
130 | #ifdef CONFIG_ARCH_OMAP3 | 137 | #ifdef CONFIG_ARCH_OMAP3 |
131 | static cycle_t omap34xx_32k_read(struct clocksource *cs) | 138 | static cycle_t omap34xx_32k_read(struct clocksource *cs) |
132 | { | 139 | { |
133 | return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10); | 140 | return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k; |
134 | } | 141 | } |
135 | #else | 142 | #else |
136 | #define omap34xx_32k_read NULL | 143 | #define omap34xx_32k_read NULL |
@@ -139,7 +146,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs) | |||
139 | #ifdef CONFIG_ARCH_OMAP4 | 146 | #ifdef CONFIG_ARCH_OMAP4 |
140 | static cycle_t omap44xx_32k_read(struct clocksource *cs) | 147 | static cycle_t omap44xx_32k_read(struct clocksource *cs) |
141 | { | 148 | { |
142 | return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10); | 149 | return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k; |
143 | } | 150 | } |
144 | #else | 151 | #else |
145 | #define omap44xx_32k_read NULL | 152 | #define omap44xx_32k_read NULL |
@@ -227,6 +234,8 @@ static int __init omap_init_clocksource_32k(void) | |||
227 | clocksource_32k.mult = clocksource_hz2mult(32768, | 234 | clocksource_32k.mult = clocksource_hz2mult(32768, |
228 | clocksource_32k.shift); | 235 | clocksource_32k.shift); |
229 | 236 | ||
237 | offset_32k = clocksource_32k.read(&clocksource_32k); | ||
238 | |||
230 | if (clocksource_register(&clocksource_32k)) | 239 | if (clocksource_register(&clocksource_32k)) |
231 | printk(err, clocksource_32k.name); | 240 | printk(err, clocksource_32k.name); |
232 | } | 241 | } |