static void cardu_usb_hsic_postsupend(void)
{
#ifdef CONFIG_TEGRA_BB_XMM_POWER
	baseband_xmm_set_power_status(BBXMM_PS_L2);
#endif
}
示例#2
0
static void cardu_usb_hsic_preresume(void)
{
#ifdef CONFIG_TEGRA_BB_XMM_POWER
	baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
#endif
}
示例#3
0
irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
{
    int value;
    struct baseband_power_platform_data *data = baseband_power_driver_data;

    value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
    pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);

    if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
        pr_err("%s - spurious irq\n", __func__);
    } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
        if (!value) {
            pr_debug("%s - IPC_AP_WAKE_INIT1"
                     " - got falling edge\n",
                     __func__);
            /* go to IPC_AP_WAKE_INIT1 state */
            ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
            /* queue work */
            queue_work(workqueue, &init1_work);
        } else {
            pr_debug("%s - IPC_AP_WAKE_INIT1"
                     " - wait for falling edge\n",
                     __func__);
        }
    } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
        if (!value) {
            pr_debug("%s - IPC_AP_WAKE_INIT2"
                     " - wait for rising edge\n",
                     __func__);
        } else {
            pr_debug("%s - IPC_AP_WAKE_INIT2"
                     " - got rising edge\n",
                     __func__);
            /* go to IPC_AP_WAKE_INIT2 state */
            ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
            /* queue work */
            queue_work(workqueue, &init2_work);
        }
    } else {
        if (!value) {
            pr_debug("%s - falling\n", __func__);
            /* First check it a CP ack or CP wake  */
            value = gpio_get_value
                    (data->modem.xmm.ipc_bb_wake);
            if (value) {
                pr_debug("cp ack for bb_wake\n");
                ipc_ap_wake_state = IPC_AP_WAKE_L;
                return IRQ_HANDLED;
            }
            spin_lock(&xmm_lock);
            wakeup_pending = true;
            if (system_suspending) {
                spin_unlock(&xmm_lock);
                pr_info("Set wakeup_pending = 1 in system_"
                        " suspending!!!\n");
            } else {
                if (baseband_xmm_powerstate ==
                        BBXMM_PS_L3) {
                    spin_unlock(&xmm_lock);
                    pr_info("CP L3 -> L0\n");
                } else if (baseband_xmm_powerstate ==
                           BBXMM_PS_L2) {
                    CP_initiated_L2toL0 = true;
                    spin_unlock(&xmm_lock);
                    baseband_xmm_set_power_status
                    (BBXMM_PS_L2TOL0);
                } else {
                    CP_initiated_L2toL0 = true;
                    spin_unlock(&xmm_lock);
                }
            }
            /* save gpio state */
            ipc_ap_wake_state = IPC_AP_WAKE_L;
        } else {
            pr_debug("%s - rising\n", __func__);
            value = gpio_get_value
                    (data->modem.xmm.ipc_hsic_active);
            if (!value) {
                pr_info("host active low: ignore request\n");
                ipc_ap_wake_state = IPC_AP_WAKE_H;
                return IRQ_HANDLED;
            }
            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 slave wakeup done ->\n");
            }
            if (reenable_autosuspend && usbdev) {
                reenable_autosuspend = false;
                queue_work(workqueue,
                           &autopm_resume_work);
            }
            modem_sleep_flag = false;
            baseband_xmm_set_power_status(
                BBXMM_PS_L0);
            /* save gpio state */
            ipc_ap_wake_state = IPC_AP_WAKE_H;
        }
    }

    return IRQ_HANDLED;
}
irqreturn_t baseband_xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
{
	int value;
	struct baseband_power_platform_data *data = baseband_power_driver_data;
	
	value = gpio_get_value(baseband_power_driver_data->modem.xmm.ipc_ap_wake);
	pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);

	if (ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY) {
		pr_err("%s - spurious irq\n", __func__);
	} else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
		if (!value) {
			pr_debug("%s - IPC_AP_WAKE_INIT1" " - got falling edge\n", __func__);
			/* go to IPC_AP_WAKE_INIT1 state */
			ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
			/* queue work */
			queue_work(workqueue, &init1_work);
		} else {
			pr_debug("%s - IPC_AP_WAKE_INIT1" " - wait for falling edge\n",	__func__);
		}
	} else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
		if (!value) {
			pr_debug("%s - IPC_AP_WAKE_INIT2" " - wait for rising edge\n",__func__);
		} else {
			pr_debug("%s - IPC_AP_WAKE_INIT2" " - got rising edge\n",__func__);
			/* go to IPC_AP_WAKE_INIT2 state */
			ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
			/* queue work */
			queue_work(workqueue, &init2_work);
		}
	} else {
		if (!value) {
			pr_debug("%s - falling\n", __func__);
			/* First check it a CP ack or CP wake  */
			value = gpio_get_value(data->modem.xmm.ipc_bb_wake);
			if (value) {
				pr_debug("cp ack for bb_wake\n");
				ipc_ap_wake_state = IPC_AP_WAKE_L;
				return IRQ_HANDLED;
			}
			spin_lock(&xmm_lock);
			wakeup_pending = true;
			if (system_suspending) {
				spin_unlock(&xmm_lock);
				pr_debug("Set wakeup_pending = 1 in system_" " suspending!!!\n");
			} else {
				if (baseband_xmm_powerstate == BBXMM_PS_L3) {
					spin_unlock(&xmm_lock);
					pr_debug("PM_ST : CP L3 -> L0\n");
				} else if (baseband_xmm_powerstate == BBXMM_PS_L2) {
					CP_initiated_L2toL0 = true;
					spin_unlock(&xmm_lock);
					baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
				} else {
					CP_initiated_L2toL0 = true;
					spin_unlock(&xmm_lock);
				}
			}
			/* save gpio state */
			ipc_ap_wake_state = IPC_AP_WAKE_L;
		} else {
			pr_debug("%s - rising\n", __func__);
			value = gpio_get_value(data->modem.xmm.ipc_hsic_active);
			//pr_debug("GPIO [R]: Host_active = %d \n",value); 
			if (!value) {
				pr_debug("host active low: ignore request\n");
				ipc_ap_wake_state = IPC_AP_WAKE_H;
				return IRQ_HANDLED;
			}
			value = gpio_get_value(data->modem.xmm.ipc_bb_wake);
			//pr_debug("GPIO [R]: Slave_wakeup = %d \n", value); 
			if (value) {
				/* Clear the slave wakeup request */
				gpio_set_value(data->modem.xmm.ipc_bb_wake, 0);
				pr_debug("GPIO [W]: Slave_wake -> 0 \n"); 
			}
			if (reenable_autosuspend && usbdev) {
			      reenable_autosuspend = false;
				struct usb_interface *intf;
				intf = usb_ifnum_to_if(usbdev, 0);
				if (usb_autopm_get_interface_async(intf) >= 0) {
					pr_debug("get_interface_async succeeded"	" - call put_interface\n");
					usb_autopm_put_interface_async(intf);
				} else {
					pr_debug("get_interface_async failed" " - do not call put_interface\n");
				}			      
			}
			modem_sleep_flag = false;
			baseband_xmm_set_power_status(BBXMM_PS_L0);
			if (short_autosuspend && enable_short_autosuspend &&
						baseband_xmm_powerstate == BBXMM_PS_L0 &&
						&usbdev->dev) 
			{
				pr_debug("set autosuspend delay %d ms\n",SHORT_AUTOSUSPEND_DELAY);
				queue_work(workqueue_susp, &work_shortsusp);				
			} 
			/* save gpio state */
			ipc_ap_wake_state = IPC_AP_WAKE_H;
		}
	}

	return IRQ_HANDLED;
}