summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/baseband-xmm-power.c
diff options
context:
space:
mode:
authorVinayak Pane <vpane@nvidia.com>2012-04-13 17:13:15 -0700
committerSimone Willett <swillett@nvidia.com>2012-04-18 16:46:32 -0700
commit69b3378dd9151627f621b40a5fe82fe697494ee3 (patch)
treef2189bc56bf100cce4f4c77c0558ca1bcf38f008 /arch/arm/mach-tegra/baseband-xmm-power.c
parent25eb47aef9013f06b3560719966e682e3064907b (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.c74
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;