msm: pm: Add API to enable/disable retention mode
On 8974 targets, retention mode voltage is controlled by the LDO
regulator, which in turn is powered through a ganged PMIC regulators. At
certain low voltage levels, the ganged PMIC will not be able to power
the LDO retention voltage. The regulator framework would invoke this
API to enable/disable retention mode in these scenarios.
When disabling retention modes, send a IPI to wakeup all online cores
out of idle, to ensure that no core is in a retention low power mode.
Also, disabled support for retention during suspend/hotplug operations
to ensure that a CPU isn't already in retention when the voltage is
lowered. This shouldn't have an effect on suspend, as the driver always
chooses the deepest sleep mode for suspend/hotplug.
Change-Id: I0af18168968c2aaf05ca99188d30762612c87de6
Signed-off-by: Mahesh Sivasubramanian <msivasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/no-pm.c b/arch/arm/mach-msm/no-pm.c
index d460c70..0db6e68 100644
--- a/arch/arm/mach-msm/no-pm.c
+++ b/arch/arm/mach-msm/no-pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2011, 2013 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -48,3 +48,4 @@
return -ENOSYS;
}
+void msm_pm_enable_retention(bool enable) {}
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index e35d843..261d433 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -118,6 +118,7 @@
static struct msm_pm_init_data_type msm_pm_init_data;
static struct hrtimer pm_hrtimer;
static struct msm_pm_sleep_ops pm_sleep_ops;
+static bool msm_pm_ldo_retention_enabled = true;
/*
* Write out the attribute.
*/
@@ -820,6 +821,14 @@
}
/* fall through */
case MSM_PM_SLEEP_MODE_RETENTION:
+ /*
+ * The Krait BHS regulator doesn't have enough head
+ * room to drive the retention voltage on LDO and so
+ * has disabled retention
+ */
+ if (!msm_pm_ldo_retention_enabled)
+ break;
+
if (!allow)
break;
@@ -995,6 +1004,34 @@
msm_pm_swfi();
}
+static void msm_pm_ack_retention_disable(void *data)
+{
+ /*
+ * This is a NULL function to ensure that the core has woken up
+ * and is safe to disable retention.
+ */
+}
+/**
+ * msm_pm_enable_retention() - Disable/Enable retention on all cores
+ * @enable: Enable/Disable retention
+ *
+ */
+void msm_pm_enable_retention(bool enable)
+{
+ msm_pm_ldo_retention_enabled = enable;
+ /*
+ * If retention is being disabled, wakeup all online core to ensure
+ * that it isn't executing retention. Offlined cores need not be woken
+ * up as they enter the deepest sleep mode, namely RPM assited power
+ * collapse
+ */
+ if (!enable)
+ smp_call_function_many(cpu_online_mask,
+ msm_pm_ack_retention_disable,
+ NULL, true);
+}
+EXPORT_SYMBOL(msm_pm_enable_retention);
+
static int msm_pm_enter(suspend_state_t state)
{
bool allow[MSM_PM_SLEEP_MODE_NR];
diff --git a/arch/arm/mach-msm/pm-data.c b/arch/arm/mach-msm/pm-data.c
index 6f4743f..08cdf5d 100644
--- a/arch/arm/mach-msm/pm-data.c
+++ b/arch/arm/mach-msm/pm-data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -30,7 +30,7 @@
[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RETENTION)] = {
.idle_supported = 1,
- .suspend_supported = 1,
+ .suspend_supported = 0,
.idle_enabled = 0,
.suspend_enabled = 0,
},
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 86d8f98..399194a 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/pm.h
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
* Author: San Mehat <san@android.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -114,6 +114,7 @@
int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode);
void msm_pm_cpu_enter_lowpower(unsigned int cpu);
void __init msm_pm_set_tz_retention_flag(unsigned int flag);
+void msm_pm_enable_retention(bool enable);
#ifdef CONFIG_MSM_PM8X60
void msm_pm_set_rpm_wakeup_irq(unsigned int irq);