예제 #1
0
static void msm_hsusb_request_host(void *handle, int request)
{
	struct msmusb_hcd *mhcd = handle;
	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
	struct msm_usb_host_platform_data *pdata = mhcd->pdata;
	struct msm_otg *otg = container_of(mhcd->xceiv, struct msm_otg, otg);

	switch (request) {
	case REQUEST_RESUME:
		usb_hcd_resume_root_hub(hcd);
		break;
	case REQUEST_START:
		if (mhcd->running)
			break;
		wake_lock(&mhcd->wlock);
		msm_xusb_pm_qos_update(mhcd, 1);
		msm_xusb_enable_clks(mhcd);
		if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
			if (otg->set_clk)
				otg->set_clk(mhcd->xceiv, 1);
		if (pdata->vbus_power)
			pdata->vbus_power(pdata->phy_info, 1);
		if (pdata->config_gpio)
			pdata->config_gpio(1);
		usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
		mhcd->running = 1;
		if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
			if (otg->set_clk)
				otg->set_clk(mhcd->xceiv, 0);
		break;
	case REQUEST_STOP:
		if (!mhcd->running)
			break;
		mhcd->running = 0;
		
		if (PHY_TYPE(pdata->phy_info) == USB_PHY_SERIAL_PMIC) {
			usb_lpm_exit(hcd);
			if (cancel_work_sync(&(mhcd->lpm_exit_work)))
				usb_lpm_exit_w(&mhcd->lpm_exit_work);
		}
		usb_remove_hcd(hcd);
		if (pdata->config_gpio)
			pdata->config_gpio(0);
		if (pdata->vbus_power)
			pdata->vbus_power(pdata->phy_info, 0);
		msm_xusb_disable_clks(mhcd);
		wake_lock_timeout(&mhcd->wlock, HZ/2);
		msm_xusb_pm_qos_update(mhcd, 0);
		if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) {
			otg->reset(mhcd->xceiv);
			otg_set_suspend(mhcd->xceiv, 1);
		}
		break;
	}
}
예제 #2
0
static int ehci_msm_bus_resume(struct usb_hcd *hcd)
{
	struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);

	usb_lpm_exit(hcd);
	if (cancel_work_sync(&(mhcd->lpm_exit_work)))
		usb_lpm_exit_w(&mhcd->lpm_exit_work);

	return ehci_bus_resume(hcd);

}
예제 #3
0
static irqreturn_t ehci_msm_irq(struct usb_hcd *hcd)
{
	struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);

	if (unlikely(mhcd->in_lpm)) {
		usb_lpm_exit(hcd);
		return IRQ_HANDLED;
	}

	return ehci_irq(hcd);
}
예제 #4
0
static void msm_hsusb_request_host(void *handle, int request)
{
	struct msmusb_hcd *mhcd = handle;
	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
	struct msm_usb_host_platform_data *pdata = mhcd->pdata;

	switch (request) {
	case REQUEST_RESUME:
		usb_hcd_resume_root_hub(hcd);
		break;
	case REQUEST_START:
		if (mhcd->running)
			break;
		wake_lock(&mhcd->wlock);
		msm_xusb_pm_qos_update(mhcd, 1);
		msm_xusb_enable_clks(mhcd);
		if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
			clk_enable(mhcd->clk);
		if (pdata->vbus_power)
			pdata->vbus_power(pdata->phy_info, 1);
		if (pdata->config_gpio)
			pdata->config_gpio(1);
		usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
		mhcd->running = 1;
		if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
			clk_disable(mhcd->clk);
		break;
	case REQUEST_STOP:
		if (!mhcd->running)
			break;
		mhcd->running = 0;
		/* come out of lpm before deregistration */
		usb_lpm_exit(hcd);
		if (cancel_work_sync(&(mhcd->lpm_exit_work)))
			usb_lpm_exit_w(&mhcd->lpm_exit_work);
		usb_remove_hcd(hcd);
		if (pdata->config_gpio)
			pdata->config_gpio(0);
		if (pdata->vbus_power)
			pdata->vbus_power(pdata->phy_info, 0);
		msm_xusb_disable_clks(mhcd);
		wake_lock_timeout(&mhcd->wlock, HZ/2);
		msm_xusb_pm_qos_update(mhcd, 0);
		break;
	}
}
예제 #5
0
static int ehci_msm_bus_resume(struct usb_hcd *hcd)
{
	struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);

	wake_lock(&mhcd->wlock);

	if (PHY_TYPE(mhcd->pdata->phy_info) == USB_PHY_INTEGRATED) {
		otg_set_suspend(mhcd->xceiv, 0);
	} else { 
		usb_lpm_exit(hcd);
		if (cancel_work_sync(&(mhcd->lpm_exit_work)))
			usb_lpm_exit_w(&mhcd->lpm_exit_work);
	}

	return ehci_bus_resume(hcd);

}
예제 #6
0
static int ehci_msm_bus_resume(struct usb_hcd *hcd)
{
    struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd);
    struct device *dev = hcd->self.controller;

    wake_lock(&mhcd->wlock);
    pm_runtime_get_noresume(dev);
    pm_runtime_resume(dev);

    if (PHY_TYPE(mhcd->pdata->phy_info) == USB_PHY_INTEGRATED) {
        usb_phy_set_suspend(mhcd->xceiv, 0);
    } else { /* PMIC serial phy */
        usb_lpm_exit(hcd);
        if (cancel_work_sync(&(mhcd->lpm_exit_work)))
            usb_lpm_exit_w(&mhcd->lpm_exit_work);
    }

    return ehci_bus_resume(hcd);

}
예제 #7
0
static void msm_hsusb_request_host(void *handle, int request)
{
    struct msmusb_hcd *mhcd = handle;
    struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
    struct msm_usb_host_platform_data *pdata = mhcd->pdata;
    struct msm_otg *otg = container_of(mhcd->xceiv, struct msm_otg, phy);
#ifdef CONFIG_USB_OTG
    struct usb_device *udev = hcd->self.root_hub;
#endif
    struct device *dev = hcd->self.controller;

    switch (request) {
#ifdef CONFIG_USB_OTG
    case REQUEST_HNP_SUSPEND:
        /* disable Root hub auto suspend. As hardware is configured
         * for peripheral mode, mark hardware is not available.
         */
        if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) {
            pm_runtime_disable(&udev->dev);
            /* Mark root hub as disconnected. This would
             * protect suspend/resume via sysfs.
             */
            udev->state = USB_STATE_NOTATTACHED;
            clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
            hcd->state = HC_STATE_HALT;
            pm_runtime_put_noidle(dev);
            pm_runtime_suspend(dev);
        }
        break;
    case REQUEST_HNP_RESUME:
        if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED) {
            pm_runtime_get_noresume(dev);
            pm_runtime_resume(dev);
            disable_irq(hcd->irq);
            ehci_msm_reset(hcd);
            ehci_msm_run(hcd);
            set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
            pm_runtime_enable(&udev->dev);
            udev->state = USB_STATE_CONFIGURED;
            enable_irq(hcd->irq);
        }
        break;
#endif
    case REQUEST_RESUME:
        usb_hcd_resume_root_hub(hcd);
        break;
    case REQUEST_START:
        if (mhcd->running)
            break;
        pm_runtime_get_noresume(dev);
        pm_runtime_resume(dev);
        wake_lock(&mhcd->wlock);
        msm_xusb_pm_qos_update(mhcd, 1);
        msm_xusb_enable_clks(mhcd);
        if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
            if (otg->set_clk)
                otg->set_clk(mhcd->xceiv, 1);
        if (pdata->vbus_power)
            pdata->vbus_power(pdata->phy_info, 1);
        if (pdata->config_gpio)
            pdata->config_gpio(1);
        usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
        mhcd->running = 1;
        if (PHY_TYPE(pdata->phy_info) == USB_PHY_INTEGRATED)
            if (otg->set_clk)
                otg->set_clk(mhcd->xceiv, 0);
        break;
    case REQUEST_STOP:
        if (!mhcd->running)
            break;
        mhcd->running = 0;
        /* come out of lpm before deregistration */
        if (PHY_TYPE(pdata->phy_info) == USB_PHY_SERIAL_PMIC) {
            usb_lpm_exit(hcd);
            if (cancel_work_sync(&(mhcd->lpm_exit_work)))
                usb_lpm_exit_w(&mhcd->lpm_exit_work);
        }
        usb_remove_hcd(hcd);
        if (pdata->config_gpio)
            pdata->config_gpio(0);
        if (pdata->vbus_power)
            pdata->vbus_power(pdata->phy_info, 0);
        msm_xusb_disable_clks(mhcd);
        wake_lock_timeout(&mhcd->wlock, HZ/2);
        msm_xusb_pm_qos_update(mhcd, 0);
        pm_runtime_put_noidle(dev);
        pm_runtime_suspend(dev);
        break;
    }
}