From b6426b90fd99bf82114465a12ff7e4da2a4c982e Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Thu, 21 Apr 2011 09:43:48 +0530 Subject: ARM: tegra: whistler: Power down/up core rail 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 Reviewed-by: Bharat Nihalani --- arch/arm/mach-tegra/board-whistler-power.c | 25 ++++++++++++++++++++++--- arch/arm/mach-tegra/include/mach/suspend.h | 5 +++++ arch/arm/mach-tegra/suspend.c | 21 +++++++++++++++++++++ 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, -- cgit v1.2.3