summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMayuresh Kulkarni <mkulkarni@nvidia.com>2010-02-20 13:31:13 +0530
committerGary King <gking@nvidia.com>2010-02-22 11:41:14 -0800
commit8fba90b4d4f400af56cf9f2e998d0562f087fcd9 (patch)
treebe9b78b4ede81cf2d87a9f72300365b442a46254
parent3f3eefc8ac980eb3fc71aea68f0572de696c5192 (diff)
tegra pm: implement suspend_ops
We implement suspend_ops->valid, suspend_ops->begin, suspend_ops->enter and suspend_ops->end. For suspend_ops->begin : Check if CPU1 is in reset or not. If not, reset it and maintain this state. For suspend_ops->end : Check if CPU1 was reseted by suspend_ops->begin. If yes, take it out of reset. For harmony board, add a timed wake lock as a WAR. For suspend_ops->enter : Do a odm query for lowest power state. Call the appropriate low power state (LP1/LP0) routine based on SOC type. Change-Id: I6f4be75978573bba94e95723c023abc091e06d1e
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-tegra/suspend_ops.c70
1 files changed, 46 insertions, 24 deletions
diff --git a/arch/arm/mach-tegra/suspend_ops.c b/arch/arm/mach-tegra/suspend_ops.c
index 0aef7afe151e..9f2a756dc3ad 100644..100755
--- a/arch/arm/mach-tegra/suspend_ops.c
+++ b/arch/arm/mach-tegra/suspend_ops.c
@@ -22,10 +22,23 @@
#include <linux/suspend.h>
#include "nvcommon.h"
+#include "nvodm_query.h"
+#include <linux/wakelock.h>
+#include <linux/cpu.h>
+
+extern void cpu_ap20_do_lp0(void);
+extern void cpu_ap20_do_lp1(void);
+extern unsigned int check_for_cpu1_reset(void);
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+static struct wake_lock suspend_ops_wake_lock;
+static bool wake_lock_initialized = false;
+#endif
+
+static bool Cpu1PoweredOff = false;
int tegra_state_valid(suspend_state_t state)
{
- printk("%s CALLED\n", __func__);
if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX)
return 1;
return 0;
@@ -33,49 +46,58 @@ int tegra_state_valid(suspend_state_t state)
int tegra_state_begin(suspend_state_t state)
{
- printk("%s CALLED with state = %d\n", __func__, state);
- return 0;
-}
-
-int tegra_state_prepare(void)
-{
- printk("%s CALLED \n", __func__);
+ if(check_for_cpu1_reset() == 0) {
+ cpu_down(1);
+ Cpu1PoweredOff = true;
+ }
return 0;
}
int tegra_state_enter(suspend_state_t state)
{
- printk("%s CALLED with state = %d\n", __func__, state);
- return 0;
-}
+ const NvOdmSocPowerStateInfo *LPStateInfo;
-void tegra_state_finish(void)
-{
- printk("%s CALLED \n", __func__);
+ LPStateInfo = NvOdmQueryLowestSocPowerState();
+ if (LPStateInfo->LowestPowerState == NvOdmSocPowerState_DeepSleep) {
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
+ /* do AP20 LP0 */
+ cpu_ap20_do_lp0();
+#endif
+ }
+ else if (LPStateInfo->LowestPowerState == NvOdmSocPowerState_Suspend) {
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
+ /* do AP20 LP1 */
+ cpu_ap20_do_lp1();
+#endif
+ }
+ return 0;
}
void tegra_state_end(void)
{
- printk("%s CALLED \n", __func__);
-}
+ if(Cpu1PoweredOff) {
+ cpu_up(1);
+ Cpu1PoweredOff = false;
+ }
-void tegra_state_recover(void)
-{
- printk("%s CALLED \n", __func__);
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ if(!wake_lock_initialized) {
+ wake_lock_init(&suspend_ops_wake_lock, WAKE_LOCK_SUSPEND, "tegra_suspend_ops");
+ wake_lock_initialized = true;
+ }
+ wake_lock_timeout(&suspend_ops_wake_lock, 1000);
+#endif
}
static struct platform_suspend_ops tegra_suspend_ops =
{
.valid = tegra_state_valid,
.begin = tegra_state_begin,
- .prepare = tegra_state_prepare,
.enter = tegra_state_enter,
- .finish = tegra_state_finish,
- .end = tegra_state_end,
- .recover = tegra_state_recover
+ .end = tegra_state_end
};
-void tegra_set_suspend_ops()
+void tegra_set_suspend_ops(void)
{
suspend_set_ops(&tegra_suspend_ops);
}