コード例 #1
0
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;
}
コード例 #2
0
ファイル: baseband-xmm-power.c プロジェクト: sparkma/kernel
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);
}