aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2014-06-11 11:18:48 -0400
committerKukjin Kim <kgene.kim@samsung.com>2014-06-16 11:23:29 -0400
commit1d80415db64b54141ef02ae58bd2f273d0ac3c38 (patch)
tree1f0447c05960c840b5d42807b783dd6bdf181161
parentcf286b405c446cc2c61e4ab210ef42e5852a6da3 (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.c9
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 */
156static void exynos4_mct_frc_start(u32 hi, u32 lo) 156static 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
182static void exynos4_frc_resume(struct clocksource *cs) 179static 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
187struct clocksource mct_frc = { 184struct clocksource mct_frc = {
@@ -200,7 +197,7 @@ static u64 notrace exynos4_read_sched_clock(void)
200 197
201static void __init exynos4_clocksource_init(void) 198static 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);