diff options
author | Chirantan Ekbote <chirantan@chromium.org> | 2014-06-11 11:18:48 -0400 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-06-16 11:23:29 -0400 |
commit | 1d80415db64b54141ef02ae58bd2f273d0ac3c38 (patch) | |
tree | 1f0447c05960c840b5d42807b783dd6bdf181161 | |
parent | cf286b405c446cc2c61e4ab210ef42e5852a6da3 (diff) |
clocksource: exynos_mct: Don't reset the counter during boot and resume
Unfortunately on some exynos systems, resetting the mct counter also
resets the architected timer counter. This can cause problems if the
architected timer driver has already been initialized because the kernel
will think that the counter has wrapped around, causing a big jump in
printk timestamps and delaying any scheduled clock events until the
counter reaches the value it had before it was reset.
The kernel code makes no assumptions about the initial value of the mct
counter so there is no reason from a software perspective to clear the
counter before starting it. This also fixes the problems described in
the previous paragraph.
Cc: Olof Johansson <olof@lixom.net>
Cc: Tomasz Figa <tomasz.figa@gmail.com>
Signed-off-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Tested-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r-- | drivers/clocksource/exynos_mct.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 8d6420013a04..f71d55f5e6e5 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c | |||
@@ -153,13 +153,10 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | /* Clocksource handling */ | 155 | /* Clocksource handling */ |
156 | static void exynos4_mct_frc_start(u32 hi, u32 lo) | 156 | static void exynos4_mct_frc_start(void) |
157 | { | 157 | { |
158 | u32 reg; | 158 | u32 reg; |
159 | 159 | ||
160 | exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L); | ||
161 | exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U); | ||
162 | |||
163 | reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); | 160 | reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON); |
164 | reg |= MCT_G_TCON_START; | 161 | reg |= MCT_G_TCON_START; |
165 | exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON); | 162 | exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON); |
@@ -181,7 +178,7 @@ static cycle_t exynos4_frc_read(struct clocksource *cs) | |||
181 | 178 | ||
182 | static void exynos4_frc_resume(struct clocksource *cs) | 179 | static void exynos4_frc_resume(struct clocksource *cs) |
183 | { | 180 | { |
184 | exynos4_mct_frc_start(0, 0); | 181 | exynos4_mct_frc_start(); |
185 | } | 182 | } |
186 | 183 | ||
187 | struct clocksource mct_frc = { | 184 | struct clocksource mct_frc = { |
@@ -200,7 +197,7 @@ static u64 notrace exynos4_read_sched_clock(void) | |||
200 | 197 | ||
201 | static void __init exynos4_clocksource_init(void) | 198 | static void __init exynos4_clocksource_init(void) |
202 | { | 199 | { |
203 | exynos4_mct_frc_start(0, 0); | 200 | exynos4_mct_frc_start(); |
204 | 201 | ||
205 | if (clocksource_register_hz(&mct_frc, clk_rate)) | 202 | if (clocksource_register_hz(&mct_frc, clk_rate)) |
206 | panic("%s: can't register clocksource\n", mct_frc.name); | 203 | panic("%s: can't register clocksource\n", mct_frc.name); |