ARM: tegra: whistler: Power down/up core rail tegra-11.2.5
authorPrashant Gaikwad <pgaikwad@nvidia.com>
Thu, 21 Apr 2011 04:13:48 +0000 (09:43 +0530)
committerVarun Colbert <vcolbert@nvidia.com>
Tue, 26 Apr 2011 01:46:45 +0000 (18:46 -0700)
program pwren signal of max8907c regulator to power down/up core rail on
deep sleep enter/exit deep sleep mode.

core_timer and core_off_timer changed as per K32.

separate_req set to false as whistler pmu has combined power requests.

Bug 817378

Change-Id: Ia95a61360079f919a039572cf8fd4597db9efd50
Reviewed-on: http://git-master/r/28435
Tested-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
arch/arm/mach-tegra/board-whistler-power.c
arch/arm/mach-tegra/include/mach/suspend.h
arch/arm/mach-tegra/suspend.c

index 425a5e6d88285adf8d418ef362efaf805469723f..bbfd4f529ad79b3a2a84943eb9143105c55010aa 100644 (file)
@@ -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;
index e6043ae614cc89660355684f33ba1fac80c01995..056d91b0a57c281721433011d6dff3d69930a81f 100644 (file)
@@ -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_ */
index 7e581b198216fc88efdaefddbc8f8d195df85e08..77c3c1c0fec0e6693a8d1c00008d9c31db73e696 100644 (file)
@@ -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,