コード例 #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
ファイル: 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);
}
コード例 #3
0
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;

	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;

	/* 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
					(pdata->ehci_device);
			else
				pr_err("%s: hsic_register is missing\n",
					__func__);
			register_hsic_device = false;
			baseband_modem_power_on(pdata);
		} else {
			/* register usb host controller */
			if (pdata->hsic_register)
				data->hsic_device = pdata->hsic_register
					(pdata->ehci_device);
			/* 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);
		forced_abort_hubevent = 0;

		xmm_power_reset_on(pdata);
	}

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

	return 0;
}
コード例 #4
0
ファイル: baseband-xmm-power.c プロジェクト: sparkma/kernel
static int baseband_xmm_power_on(struct platform_device *device)
{
	struct baseband_power_platform_data *data
		= (struct baseband_power_platform_data *)
			device->dev.platform_data;
	int ret;

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

	/* check for platform data */
	if (!data) {
		pr_err("%s: !data\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;

	if (modem_ver < XMM_MODEM_VER_1130)
		ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
	else
		ipc_ap_wake_state = IPC_AP_WAKE_INIT2;

	pr_debug("%s wake_st(%d) modem version %d\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 (data->hsic_register)
				data->modem.xmm.hsic_device =
						data->hsic_register();
			else
				pr_err("%s: hsic_register is missing\n",
					__func__);
			register_hsic_device = false;
		} else {
			/* register usb host controller */
			if (data->hsic_register)
				data->modem.xmm.hsic_device =
							data->hsic_register();
			/* turn on modem */
			pr_debug("%s call baseband_modem_power_on\n", __func__);
			baseband_modem_power_on(data);
		}
	}
	ret = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
	if (ret < 0)
		pr_err("%s: enable_irq_wake error\n", __func__);

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

	return 0;
}
コード例 #5
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 (!gpio_get_value(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);
		}
		if (register_hsic_device != true && wakeup_pending == false) {
			gpio_set_value(data->modem.xmm.ipc_hsic_active, 0);
			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();
		} else
			goto exit_without_state_change;
	default:
		break;
	}
	baseband_xmm_powerstate = status;
	pr_debug("BB XMM POWER STATE = %d\n", status);
	return;

exit_without_state_change:
	pr_info("BB XMM POWER STATE = %d (not change to %d)\n",
			baseband_xmm_powerstate, status);
	return;
}
コード例 #6
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(%d),o(%d)\n", __func__, status, baseband_xmm_powerstate );

	if (baseband_xmm_powerstate == status)
		return;

	switch (status) {
	case BBXMM_PS_L0:
		if (modem_sleep_flag) {
			pr_debug("%s Resume from L3 without calling resume" "function\n",  __func__);
				baseband_xmm_power_driver_handle_resume(data);
		}	
		pr_debug("PM_ST : L0\n");
		baseband_xmm_powerstate = status;
		if (!wake_lock_active(&wakelock))
			wake_lock(&wakelock);
		value = gpio_get_value(data->modem.xmm.ipc_hsic_active);
		//pr_debug("GPIO [R]: before L0 Host_active = %d \n", value); 
		if (!value) {
			gpio_set_value(data->modem.xmm.ipc_hsic_active, 1);
			pr_debug("GPIO [W]: L0 Host_active -> 1 \n"); 
		}
		if (modem_power_on) {
			modem_power_on = false;
			baseband_modem_power_on(data);
		}
		pr_debug("gpio host active high->\n");
		break;
		
	case BBXMM_PS_L2:
		pr_debug("PM_ST : L2\n");
		baseband_xmm_powerstate = status;
		spin_lock_irqsave(&xmm_lock, flags);
		if (wakeup_pending) {
			spin_unlock_irqrestore(&xmm_lock, flags);
			baseband_xmm_power_L2_resume();
		 } else {
			spin_unlock_irqrestore(&xmm_lock, flags);
			if (wake_lock_active(&wakelock))
				wake_unlock(&wakelock);
		modem_sleep_flag = true;
		}
		if (short_autosuspend && enable_short_autosuspend && &usbdev->dev) {
			pr_debug("autosuspend delay %d ms, disable short_autosuspend\n",DEFAULT_AUTOSUSPEND_DELAY);
			queue_work(workqueue_susp, &work_defaultsusp);
			short_autosuspend = false;
		}
		break;
		
	case BBXMM_PS_L3:
		if (baseband_xmm_powerstate == BBXMM_PS_L2TOL0) {
			if (!gpio_get_value(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_debug("%s: releasing wakelock before L3\n", __func__);
			wake_unlock(&wakelock);
		}
		if (wakeup_pending == false) {
			gpio_set_value(data->modem.xmm.ipc_hsic_active, 0);
			pr_debug("gpio host active low->\n");
		}
		break;
	case BBXMM_PS_L2TOL0:
		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);
			baseband_xmm_power_L2_resume();
		}
		baseband_xmm_powerstate = status;
		break;
	default:
		baseband_xmm_powerstate = status;
		break;
	}
	pr_debug("BB XMM POWER STATE = %s(%d)\n", pwrstate_cmt[status], status);
}
コード例 #7
0
static int baseband_xmm_power_on(struct platform_device *device)
{
	struct baseband_power_platform_data *data
		= (struct baseband_power_platform_data *)
			device->dev.platform_data;
	int ret;
				
	pr_debug("%s {\n", __func__);

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

     if (baseband_xmm_powerstate != BBXMM_PS_UNINIT)
            return -EINVAL;

	/* reset the state machine */
	baseband_xmm_powerstate = BBXMM_PS_INIT;
	modem_sleep_flag = false;

	if (modem_ver < XMM_MODEM_VER_1130)
		ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
	else
		ipc_ap_wake_state = IPC_AP_WAKE_INIT2;

	pr_debug("%s - %d\n", __func__, __LINE__);

	/* 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 (data->hsic_register)
				data->modem.xmm.hsic_device = data->hsic_register();
			else
				pr_err("%s: hsic_register is missing\n",__func__);
			register_hsic_device = false;
		} else {
			/* register usb host controller */
			if (data->hsic_register)
				data->modem.xmm.hsic_device = data->hsic_register();
			/* turn on modem */
			pr_debug("%s call baseband_modem_power_on\n", __func__);
			baseband_modem_power_on(data);
		}
	} else {                
		if (modem_ver >= XMM_MODEM_VER_1145) {
			pr_debug("%s: ver > 1145: IPC_AP_WAKE_IRQ_READY\n", __func__);
			ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
			baseband_xmm_powerstate = BBXMM_PS_UNINIT;
			CP_initiated_L2toL0 = false;
			enum_repeat = ENUM_REPEAT_TRY_CNT;
			printk("##@%s forced_abort_hubevent <- 0\n", __func__);
			forced_abort_hubevent = 0;
	
			baseband_xmm_power_work->state = BBXMM_WORK_INIT;
			queue_work(workqueue,(struct work_struct *) baseband_xmm_power_work);
		} else
			pr_err("%s: Error, no support cp ver\n", __func__);
	}
    ret = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
    if (ret < 0)
           pr_err("%s: enable_irq_wake error\n", __func__);
	pr_debug("%s }\n", __func__);

	return 0;
}
コード例 #8
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);
}