static int xmm_power_on(struct platform_device *device)
{
	struct baseband_power_platform_data *pdata =
			device->dev.platform_data;
	struct xmm_power_data *data = &xmm_power_drv_data;
	int ret;

	pr_debug("%s {\n", __func__);

	/* check for platform data */
	if (!pdata) {
		pr_err("%s: !pdata\n", __func__);
		return -EINVAL;
	}
	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;
	ipc_ap_wake_state = IPC_AP_WAKE_INIT2;

	pr_debug("%s wake_st(%d) modem version %lu\n", __func__,
				ipc_ap_wake_state, modem_ver);

	/* register usb host controller */
	if (!modem_flash) {
		pr_debug("%s - %d\n", __func__, __LINE__);
		/* register usb host controller only once */
		if (register_hsic_device) {
			pr_debug("%s: register usb host controller\n",
				__func__);
			modem_power_on = true;
			if (pdata->hsic_register)
				data->hsic_device = pdata->hsic_register();
			else
				pr_err("%s: hsic_register is missing\n",
					__func__);
			register_hsic_device = false;
		} else {
			/* register usb host controller */
			if (pdata->hsic_register)
				data->hsic_device = pdata->hsic_register();
			/* turn on modem */
			pr_debug("%s call baseband_modem_power_on_async\n",
								__func__);
			baseband_modem_power_on_async(pdata);
		}
	}
	ret = enable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
	if (ret < 0)
		pr_err("%s: enable_irq_wake error\n", __func__);
	pr_debug("%s }\n", __func__);

	return 0;
}
Esempio n. 2
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);
}
static int xmm_power_on(struct platform_device *device)
{
	struct baseband_power_platform_data *pdata =
			device->dev.platform_data;
	struct xmm_power_data *data = &xmm_power_drv_data;
	unsigned long flags;
	int ret;

	pr_debug("%s {\n", __func__);

	/* check for platform data */
	if (!pdata) {
		pr_err("%s: !pdata\n", __func__);
		return -EINVAL;
	}
	if (baseband_xmm_get_power_status() != BBXMM_PS_UNINIT)
		return -EINVAL;

	tegra_baseband_rail_on();

	/* reset the state machine */
	baseband_xmm_set_power_status(BBXMM_PS_INIT);
	modem_sleep_flag = false;
	modem_acked_resume = true;

	pr_debug("%s wake_st(%d) modem version %lu\n", __func__,
				ipc_ap_wake_state, modem_ver);

	/* register usb host controller */
	if (!modem_flash) {
		pr_debug("%s - %d\n", __func__, __LINE__);

		spin_lock_irqsave(&xmm_lock, flags);
		ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
		spin_unlock_irqrestore(&xmm_lock, flags);

		/* register usb host controller only once */
		if (register_hsic_device) {
			pr_debug("%s: register usb host controller\n",
				__func__);
			modem_power_on = true;
			if (pdata->hsic_register)
				data->hsic_device = pdata->hsic_register();
			else
				pr_err("%s: hsic_register is missing\n",
					__func__);
			register_hsic_device = false;
		} else {
			/* register usb host controller */
			if (pdata->hsic_register)
				data->hsic_device = pdata->hsic_register();
			/* turn on modem */
			pr_debug("%s call baseband_modem_power_on_async\n",
								__func__);
			baseband_modem_power_on_async(pdata);
		}
	} else {
		/* reset flashed modem then it will respond with
		 * ap-wake rising followed by falling gpio
		 */

		pr_debug("%s: reset flash modem\n", __func__);

		modem_power_on = false;
		spin_lock_irqsave(&xmm_lock, flags);
		ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
		spin_unlock_irqrestore(&xmm_lock, flags);
		gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);

		xmm_power_reset_on(pdata);
	}

	ret = enable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
	if (ret < 0)
		pr_err("%s: enable_irq_wake error\n", __func__);
	pr_debug("%s }\n", __func__);

	return 0;
}