From: Xinyu Chen Date: Fri, 25 May 2012 03:39:15 +0000 (+0800) Subject: ENGR00210850 mx6: boot failure with local timer and wait mode enabled X-Git-Tag: v3.0.35-fsl~971 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=7183f5365fab2014437e5860c0f108ceb7a7a155;p=karo-tx-linux.git ENGR00210850 mx6: boot failure with local timer and wait mode enabled Previous patch only check the condition that GPT broadcast event is ready or not before doing clock event switch. It's not enough, as the clock switch from local timer to GPT broadcast must be happen after GPT broadcast clock event setup and current cpu's clock device switch to local timer clock event. Otherwise, we will have chance that cpu exit the wait mode and switch back clock event without local timer event setup correctly. Signed-off-by: Xinyu Chen --- diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 1886649f9abb..943b757997d6 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -217,12 +219,6 @@ extern int tick_broadcast_oneshot_active(void); if (enable_wait_mode) { u32 reg; int cpu = smp_processor_id(); -#ifdef CONFIG_LOCAL_TIMERS - if (!tick_broadcast_oneshot_active()) - return; - - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); -#endif *((char *)(&num_cpu_idle_lock) + (char)cpu) = 0x0; mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); if (arm_mem_clked_in_wait || mem_clk_on_in_wait) { @@ -249,6 +245,13 @@ extern int tick_broadcast_oneshot_active(void); __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR); } else { +#ifdef CONFIG_LOCAL_TIMERS + if (!tick_broadcast_oneshot_active() + || !tick_oneshot_mode_active()) + return; + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); +#endif if (low_bus_freq_mode || audio_bus_freq_mode) mx6_wait((void *)&num_cpu_idle_lock, (void *)&num_cpu_idle, @@ -257,10 +260,10 @@ extern int tick_broadcast_oneshot_active(void); mx6_wait((void *)&num_cpu_idle_lock, (void *)&num_cpu_idle, wait_mode_arm_podf, cur_arm_podf - 1); - } #ifdef CONFIG_LOCAL_TIMERS - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); #endif + } } else { mxc_cpu_lp_set(WAIT_CLOCKED); cpu_do_idle();