summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/board-whistler-power.c25
-rw-r--r--arch/arm/mach-tegra/include/mach/suspend.h5
-rw-r--r--arch/arm/mach-tegra/suspend.c21
3 files changed, 48 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/board-whistler-power.c b/arch/arm/mach-tegra/board-whistler-power.c
index 425a5e6d8828..bbfd4f529ad7 100644
--- a/arch/arm/mach-tegra/board-whistler-power.c
+++ b/arch/arm/mach-tegra/board-whistler-power.c
@@ -207,10 +207,27 @@ static struct platform_device *whistler_max8907c_power_devices[] = {
&max8907c_LDO20_device,
};
+static int whistler_max8907c_setup(void)
+{
+ int ret;
+
+ /*
+ * Configure PWREN, and attach CPU V1 rail to it.
+ * TODO: h/w events (power cycle, reset, battery low) auto-disables PWREN.
+ * Only soft reset (not supported) requires s/w to disable PWREN explicitly
+ */
+ ret = max8907c_pwr_en_config();
+ if (ret != 0)
+ return ret;
+
+ return max8907c_pwr_en_attach();
+}
+
static struct max8907c_platform_data max8907c_pdata = {
.num_subdevs = ARRAY_SIZE(whistler_max8907c_power_devices),
.subdevs = whistler_max8907c_power_devices,
.irq_base = TEGRA_NR_IRQS,
+ .max8907c_setup = whistler_max8907c_setup,
};
static struct i2c_board_info __initdata whistler_regulators[] = {
@@ -225,9 +242,9 @@ static struct tegra_suspend_platform_data whistler_suspend_data = {
.cpu_timer = 2000,
.cpu_off_timer = 1000,
.suspend_mode = TEGRA_SUSPEND_LP0,
- .core_timer = 0x7e7e,
- .core_off_timer = 0xf,
- .separate_req = true,
+ .core_timer = 0x7e,
+ .core_off_timer = 0xc00,
+ .separate_req = false,
.corereq_high = true,
.sysclkreq_high = true,
.wake_enb = TEGRA_WAKE_KBC_EVENT,
@@ -255,6 +272,8 @@ int __init whistler_regulator_init(void)
i2c_register_board_info(4, whistler_regulators, 1);
+ tegra_deep_sleep = max8907c_deep_sleep;
+
tegra_init_suspend(&whistler_suspend_data);
return 0;
diff --git a/arch/arm/mach-tegra/include/mach/suspend.h b/arch/arm/mach-tegra/include/mach/suspend.h
index e6043ae614cc..056d91b0a57c 100644
--- a/arch/arm/mach-tegra/include/mach/suspend.h
+++ b/arch/arm/mach-tegra/include/mach/suspend.h
@@ -77,4 +77,9 @@ void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any);
void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat);
+/*
+ * Callbacks for platform drivers to implement.
+ */
+extern void (*tegra_deep_sleep)(int);
+
#endif /* _MACH_TEGRA_SUSPEND_H_ */
diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c
index 7e581b198216..77c3c1c0fec0 100644
--- a/arch/arm/mach-tegra/suspend.c
+++ b/arch/arm/mach-tegra/suspend.c
@@ -701,8 +701,29 @@ static int tegra_suspend_enter(suspend_state_t state)
return 0;
}
+/*
+ * Function pointers to optional board specific function
+ */
+void (*tegra_deep_sleep)(int);
+EXPORT_SYMBOL(tegra_deep_sleep);
+
+static int tegra_suspend_prepare(void)
+{
+ if ((current_suspend_mode == TEGRA_SUSPEND_LP0) && tegra_deep_sleep)
+ tegra_deep_sleep(1);
+ return 0;
+}
+
+static void tegra_suspend_finish(void)
+{
+ if ((current_suspend_mode == TEGRA_SUSPEND_LP0) && tegra_deep_sleep)
+ tegra_deep_sleep(0);
+}
+
static struct platform_suspend_ops tegra_suspend_ops = {
.valid = suspend_valid_only_mem,
+ .prepare = tegra_suspend_prepare,
+ .finish = tegra_suspend_finish,
.begin = tegra_suspend_begin,
.prepare_late = tegra_suspend_prepare_late,
.wake = tegra_suspend_wake,