コード例 #1
0
/* 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);
}
コード例 #2
0
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);
}