/* this function holds xmm_lock */ void baseband_xmm_set_power_status(unsigned int status) { struct baseband_power_platform_data *data = xmm_power_drv_data.pdata; int value = 0; unsigned long flags; if (baseband_xmm_get_power_status() == status) return; /* avoid prints inside spinlock */ if (status <= BBXMM_PS_L2) pr_info("%s\n", status == BBXMM_PS_L0 ? "L0" : "L2"); spin_lock_irqsave(&xmm_lock, flags); switch (status) { case BBXMM_PS_L0: baseband_xmm_powerstate = status; if (!wake_lock_active(&wakelock)) wake_lock_timeout(&wakelock, HZ*2); /* pull hsic_active high for enumeration */ value = gpio_get_value(data->modem.xmm.ipc_hsic_active); if (!value) { pr_debug("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); } /* cp acknowledgment for ap L2->L0 wake */ if (!modem_acked_resume) pr_err("%s: CP didn't ack usb-resume\n", __func__); value = gpio_get_value(data->modem.xmm.ipc_bb_wake); if (value) { /* clear the slave wakeup request */ gpio_set_value(data->modem.xmm.ipc_bb_wake, 0); pr_debug("gpio bb_wake done low\n"); } break; case BBXMM_PS_L2: modem_acked_resume = false; if (wakeup_pending) { spin_unlock_irqrestore(&xmm_lock, flags); pr_debug("%s: wakeup pending\n", __func__); xmm_power_l2_resume(); spin_lock_irqsave(&xmm_lock, flags); break; } else { if (wake_lock_active(&wakelock)) wake_unlock(&wakelock); modem_sleep_flag = true; } baseband_xmm_powerstate = status; break; case BBXMM_PS_L2TOL0: pr_debug("L2TOL0\n"); system_suspending = false; wakeup_pending = false; /* do this only from L2 state */ if (baseband_xmm_powerstate == BBXMM_PS_L2) { baseband_xmm_powerstate = status; spin_unlock_irqrestore(&xmm_lock, flags); xmm_power_l2_resume(); spin_lock_irqsave(&xmm_lock, flags); } baseband_xmm_powerstate = status; break; default: baseband_xmm_powerstate = status; break; } spin_unlock_irqrestore(&xmm_lock, flags); pr_debug("BB XMM POWER STATE = %d\n", status); }
void baseband_xmm_set_power_status(unsigned int status) { struct baseband_power_platform_data *data = xmm_power_drv_data.pdata; int value = 0; unsigned long flags; if (baseband_xmm_powerstate == status) return; pr_debug("%s\n", __func__); switch (status) { case BBXMM_PS_L0: if (modem_sleep_flag) { /* We dont have L3 state now, should be handled from L2 * xmm_power_driver_handle_resume(data); */ } pr_info("L0\n"); baseband_xmm_powerstate = status; if (!wake_lock_active(&wakelock)) wake_lock_timeout(&wakelock, HZ*2); value = gpio_get_value(data->modem.xmm.ipc_hsic_active); pr_debug("before L0 ipc_hsic_active=%d\n", value); if (!value) { pr_debug("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); } break; case BBXMM_PS_L2: pr_info("L2\n"); baseband_xmm_powerstate = status; spin_lock_irqsave(&xmm_lock, flags); if (wakeup_pending) { spin_unlock_irqrestore(&xmm_lock, flags); pr_debug("%s: wakeup pending\n", __func__); xmm_power_l2_resume(); } else { spin_unlock_irqrestore(&xmm_lock, flags); if (wake_lock_active(&wakelock)) wake_unlock(&wakelock); modem_sleep_flag = true; } break; case BBXMM_PS_L2TOL0: pr_debug("L2TOL0\n"); spin_lock_irqsave(&xmm_lock, flags); system_suspending = false; wakeup_pending = false; spin_unlock_irqrestore(&xmm_lock, flags); /* 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); xmm_power_l2_resume(); } baseband_xmm_powerstate = status; break; default: baseband_xmm_powerstate = status; break; } pr_debug("BB XMM POWER STATE = %d\n", status); }