static int baseband_xmm_power_off(struct platform_device *device) { struct baseband_power_platform_data *data; int ret; unsigned long flags; pr_debug("%s {\n", __func__); if (baseband_xmm_powerstate == BBXMM_PS_UNINIT) return -EINVAL; /* check for device / platform data */ if (!device) { pr_err("%s: !device\n", __func__); return -EINVAL; } data = (struct baseband_power_platform_data *) device->dev.platform_data; if (!data) { pr_err("%s: !data\n", __func__); return -EINVAL; } ipc_ap_wake_state = IPC_AP_WAKE_UNINIT; ret = disable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake)); if (ret < 0) pr_err("%s: disable_irq_wake error\n", __func__); /* unregister usb host controller */ if (data->hsic_unregister) data->hsic_unregister(data->modem.xmm.hsic_device); else pr_err("%s: hsic_unregister is missing\n", __func__); /* set IPC_HSIC_ACTIVE low */ gpio_set_value(baseband_power_driver_data-> modem.xmm.ipc_hsic_active, 0); /* wait 20 ms */ mdelay(20); /* drive bb_rst low */ gpio_set_value(data->modem.xmm.bb_rst, 0); mdelay(1); baseband_xmm_powerstate = BBXMM_PS_UNINIT; modem_sleep_flag = false; CP_initiated_L2toL0 = false; spin_lock_irqsave(&xmm_lock, flags); wakeup_pending = false; system_suspending = false; 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; }
void baseband_xmm_set_power_status(unsigned int status) { struct baseband_power_platform_data *data = baseband_power_driver_data; int value = 0; unsigned long flags; pr_debug("%s\n", __func__); if (baseband_xmm_powerstate == status) return; switch (status) { case BBXMM_PS_L0: if (modem_sleep_flag) { pr_info("%s Resume from L3 without calling resume" "function\n", __func__); baseband_xmm_power_driver_handle_resume(data); } pr_info("L0\n"); value = gpio_get_value(data->modem.xmm.ipc_hsic_active); pr_debug("before L0 ipc_hsic_active=%d\n", value); if (!value) { pr_debug("before L0 gpio set ipc_hsic_active=1 ->\n"); gpio_set_value(data->modem.xmm.ipc_hsic_active, 1); } if (modem_power_on) { modem_power_on = false; baseband_modem_power_on(data); } if (!wake_lock_active(&wakelock)) wake_lock(&wakelock); pr_debug("gpio host active high->\n"); break; case BBXMM_PS_L2: pr_info("L2\n"); wake_unlock(&wakelock); modem_sleep_flag = true; break; case BBXMM_PS_L3: if (baseband_xmm_powerstate == BBXMM_PS_L2TOL0) { if (!data->modem.xmm.ipc_ap_wake) { spin_lock_irqsave(&xmm_lock, flags); wakeup_pending = true; spin_unlock_irqrestore(&xmm_lock, flags); pr_info("%s: L2 race condition-CP wakeup" " pending\n", __func__); } } pr_info("L3\n"); if (wake_lock_active(&wakelock)) { pr_info("%s: releasing wakelock before L3\n", __func__); wake_unlock(&wakelock); } gpio_set_value(data->modem.xmm.ipc_hsic_active, 0); /* do this only from L2 state (going to suspend) */ if (baseband_xmm_powerstate == BBXMM_PS_L2) tegra_baseband_rail_off(); pr_debug("gpio host active low->\n"); break; case BBXMM_PS_L2TOL0: /* do this only from L2 state */ if (baseband_xmm_powerstate == BBXMM_PS_L2) { baseband_xmm_powerstate = status; pr_debug("BB XMM POWER STATE = %d\n", status); baseband_xmm_power_L2_resume(); } break; case BBXMM_PS_L3TOL0: /* poweron rail for L3 -> L0 (system resume) */ pr_debug("BB XMM L3 -> L0, turning on power rail.\n"); tegra_baseband_rail_on(); break; default: break; } baseband_xmm_powerstate = status; pr_debug("BB XMM POWER STATE = %d\n", status); }