Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933609AbaFIWpe (ORCPT ); Mon, 9 Jun 2014 18:45:34 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:56749 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932495AbaFIWp2 (ORCPT ); Mon, 9 Jun 2014 18:45:28 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Roger Quadros , Kevin Hilman , Tony Lindgren , Daniel Lezcano , Santosh Shilimkar Subject: [PATCH 3.14 21/78] ARM: OMAP4: Fix the boot regression with CPU_IDLE enabled Date: Mon, 9 Jun 2014 15:48:01 -0700 Message-Id: <20140609224814.033264279@linuxfoundation.org> X-Mailer: git-send-email 1.9.0 In-Reply-To: <20140609224813.282275135@linuxfoundation.org> References: <20140609224813.282275135@linuxfoundation.org> User-Agent: quilt/0.63-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Santosh Shilimkar commit 4b353a706a86598ba47307c47301c3c428b79e09 upstream. On OMAP4 panda board, there have been several bug reports about boot hang and lock-ups with CPU_IDLE enabled. The root cause of the issue is missing interrupts while in idle state. Commit cb7094e8 {cpuidle / omap4 : use CPUIDLE_FLAG_TIMER_STOP flag} moved the broadcast notifiers to common code for right reasons but on OMAP4 which suffers from a nasty ROM code bug with GIC, commit ff999b8a {ARM: OMAP4460: Workaround for ROM bug ..}, we loose interrupts which leads to issues like lock-up, hangs etc. Patch reverts commit cb7094 {cpuidle / omap4 : use CPUIDLE_FLAG_TIMER_STOP flag} and 54769d6 {cpuidle: OMAP4: remove timer broadcast initialization} to avoid the issue. With this change, OMAP4 panda boards, the mentioned issues are getting fixed. We no longer loose interrupts which was the cause of the regression. Fixes: cb7094e8 (cpuidle / omap4 : use CPUIDLE_FLAG_TIMER_STOP flag) Fixes: ff999b8a (cpuidle: OMAP4: remove timer broadcast initialization) Cc: Roger Quadros Cc: Kevin Hilman Cc: Tony Lindgren Cc: Daniel Lezcano Reported-tested-by: Roger Quadros Reported-tested-by: Kevin Hilman Tested-by: Tony Lindgren Signed-off-by: Santosh Shilimkar Signed-off-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/cpuidle44xx.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,7 @@ static int omap_enter_idle_coupled(struc { struct idle_statedata *cx = state_ptr + index; u32 mpuss_can_lose_context = 0; + int cpu_id = smp_processor_id(); /* * CPU0 has to wait and stay ON until CPU1 is OFF state. @@ -110,6 +112,8 @@ static int omap_enter_idle_coupled(struc mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) && (cx->mpu_logic_state == PWRDM_POWER_OFF); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); + /* * Call idle CPU PM enter notifier chain so that * VFP and per CPU interrupt context is saved. @@ -165,6 +169,8 @@ static int omap_enter_idle_coupled(struc if (dev->cpu == 0 && mpuss_can_lose_context) cpu_cluster_pm_exit(); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); + fail: cpuidle_coupled_parallel_barrier(dev, &abort_barrier); cpu_done[dev->cpu] = false; @@ -172,6 +178,16 @@ fail: return index; } +/* + * For each cpu, setup the broadcast timer because local timers + * stops for the states above C1. + */ +static void omap_setup_broadcast_timer(void *arg) +{ + int cpu = smp_processor_id(); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); +} + static struct cpuidle_driver omap4_idle_driver = { .name = "omap4_idle", .owner = THIS_MODULE, @@ -189,8 +205,7 @@ static struct cpuidle_driver omap4_idle_ /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ .exit_latency = 328 + 440, .target_residency = 960, - .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED | - CPUIDLE_FLAG_TIMER_STOP, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, .enter = omap_enter_idle_coupled, .name = "C2", .desc = "CPUx OFF, MPUSS CSWR", @@ -199,8 +214,7 @@ static struct cpuidle_driver omap4_idle_ /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ .exit_latency = 460 + 518, .target_residency = 1100, - .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED | - CPUIDLE_FLAG_TIMER_STOP, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, .enter = omap_enter_idle_coupled, .name = "C3", .desc = "CPUx OFF, MPUSS OSWR", @@ -231,5 +245,8 @@ int __init omap4_idle_init(void) if (!cpu_clkdm[0] || !cpu_clkdm[1]) return -ENODEV; + /* Configure the broadcast timer on each cpu */ + on_each_cpu(omap_setup_broadcast_timer, NULL, 1); + return cpuidle_register(&omap4_idle_driver, cpu_online_mask); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/