diff options
author | Vinayak Pane <vpane@nvidia.com> | 2012-04-13 17:13:15 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-04-18 16:46:32 -0700 |
commit | 69b3378dd9151627f621b40a5fe82fe697494ee3 (patch) | |
tree | f2189bc56bf100cce4f4c77c0558ca1bcf38f008 /arch/arm/mach-tegra/baseband-xmm-power.c | |
parent | 25eb47aef9013f06b3560719966e682e3064907b (diff) |
arm: tegra: enterprise: disable dsi_csi_rail in LP0
AVDD_DSI_CSI is shared by modem and dsi. If DSI turns
off this rail then HSIC fails after wakeup from modem.
This patch provides a way to turn on this rail from
modem as well as from DSI. Create two virtual power rails
from avdd_csi_dsi to control it from both the drivers separately.
This is enterprise specific change as per the power rail layout.
Bug 920881
(cherry picked from commit ab52b51c59f776ae770d48a28a2744e2db2e5d2f)
Reviewed-on: http://git-master/r/85656
Change-Id: I2e9c04a8f4e8d6fd20584b4e75657c1cb6d5c8bd
Signed-off-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-on: http://git-master/r/89134
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Puneet Saxena <puneets@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/baseband-xmm-power.c')
-rw-r--r-- | arch/arm/mach-tegra/baseband-xmm-power.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/baseband-xmm-power.c b/arch/arm/mach-tegra/baseband-xmm-power.c index 0e642d8ebcb3..2d41abc8571a 100644 --- a/arch/arm/mach-tegra/baseband-xmm-power.c +++ b/arch/arm/mach-tegra/baseband-xmm-power.c @@ -33,6 +33,7 @@ #include <linux/suspend.h> #include <mach/usb_phy.h> #include "board.h" +#include "board-enterprise.h" #include "devices.h" #include "gpio-names.h" #include "baseband-xmm-power.h" @@ -107,11 +108,70 @@ static bool modem_sleep_flag; static spinlock_t xmm_lock; static DEFINE_MUTEX(xmm_onoff_mutex); static bool system_suspending; +static struct regulator *enterprise_hsic_reg; +static bool _hsic_reg_status; static void baseband_xmm_power_L2_resume(void); static int baseband_xmm_power_driver_handle_resume( struct baseband_power_platform_data *data); +static int tegra_baseband_rail_on(void) +{ + int ret; + struct board_info bi; + tegra_get_board_info(&bi); + + /* only applicable to enterprise */ + if (bi.board_id != BOARD_E1197) + return 0; + + if (_hsic_reg_status == true) + return 0; + + if (enterprise_hsic_reg == NULL) { + enterprise_hsic_reg = regulator_get(NULL, "avdd_hsic"); + if (IS_ERR_OR_NULL(enterprise_hsic_reg)) { + pr_err("xmm: could not get regulator vddio_hsic\n"); + enterprise_hsic_reg = NULL; + return PTR_ERR(enterprise_hsic_reg); + } + } + ret = regulator_enable(enterprise_hsic_reg); + if (ret < 0) { + pr_err("xmm: failed to enable regulator\n"); + return ret; + } + _hsic_reg_status = true; + return 0; +} + +static int tegra_baseband_rail_off(void) +{ + int ret; + struct board_info bi; + tegra_get_board_info(&bi); + + /* only applicable to enterprise */ + if (bi.board_id != BOARD_E1197) + return 0; + + if (_hsic_reg_status == false) + return 0; + + if (IS_ERR_OR_NULL(enterprise_hsic_reg)) { + pr_err("xmm: unbalanced disable on vddio_hsic regulator\n"); + enterprise_hsic_reg = NULL; + return PTR_ERR(enterprise_hsic_reg); + } + ret = regulator_disable(enterprise_hsic_reg); + if (ret < 0) { + pr_err("xmm: failed to disable regulator\n"); + return ret; + } + _hsic_reg_status = false; + return 0; +} + static int baseband_modem_power_on(struct baseband_power_platform_data *data) { /* set IPC_HSIC_ACTIVE active */ @@ -146,6 +206,8 @@ static int baseband_xmm_power_on(struct platform_device *device) if (baseband_xmm_powerstate != BBXMM_PS_UNINIT) return -EINVAL; + tegra_baseband_rail_on(); + /* reset the state machine */ baseband_xmm_powerstate = BBXMM_PS_INIT; modem_sleep_flag = false; @@ -245,6 +307,8 @@ static int baseband_xmm_power_off(struct platform_device *device) spin_unlock_irqrestore(&xmm_lock, flags); /* start registration process once again on xmm on */ register_hsic_device = true; + + tegra_baseband_rail_off(); pr_debug("%s }\n", __func__); return 0; @@ -358,6 +422,10 @@ void baseband_xmm_set_power_status(unsigned int status) } } pr_info("L3\n"); + /* system is going to suspend */ + if (baseband_xmm_powerstate == BBXMM_PS_L2) + tegra_baseband_rail_off(); + baseband_xmm_powerstate = status; spin_lock_irqsave(&xmm_lock, flags); system_suspending = false; @@ -383,6 +451,12 @@ void baseband_xmm_set_power_status(unsigned int status) } baseband_xmm_powerstate = status; break; + case BBXMM_PS_L3TOL0: + /* poweron rail for L3 -> L0 (system resume) */ + pr_debug("L3 -> L0, turning on power rail.\n"); + tegra_baseband_rail_on(); + baseband_xmm_powerstate = status; + break; default: baseband_xmm_powerstate = status; break; |