static int s5p_ehci_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); struct usb_hcd *hcd = s5p_ehci->hcd; struct ehci_hcd *ehci = hcd_to_ehci(hcd); unsigned long flags; int rc = 0; #if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) rc = get_hostwake_state(); if (rc) { pr_info("%s: suspend fail by host wakeup irq\n", __func__); pm_runtime_resume(&pdev->dev); return -EBUSY; } #endif if (time_before(jiffies, ehci->next_statechange)) usleep_range(10000, 11000); /* Root hub was already suspended. Disable irq emission and * mark HW unaccessible, bail out if RH has been resumed. Use * the spinlock to properly synchronize with possible pending * RH suspend or resume activity. * * This is still racy as hcd->state is manipulated outside of * any locks =P But that will be a different fix. */ spin_lock_irqsave(&ehci->lock, flags); if (hcd->state != HC_STATE_SUSPENDED && hcd->state != HC_STATE_HALT) { spin_unlock_irqrestore(&ehci->lock, flags); return -EINVAL; } ehci_writel(ehci, 0, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); spin_unlock_irqrestore(&ehci->lock, flags); if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); #if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) set_host_states(0); #endif clk_disable(s5p_ehci->clk); return rc; }
static void s5p_wait_for_cp_resume(struct platform_device *pdev, struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); u32 __iomem *portsc ; u32 val32, retry_cnt = 0; portsc = &ehci->regs->port_status[CP_PORT-1]; #if !defined(CONFIG_MDM_HSIC_PM) set_host_states(1); #endif do { usleep_range(10000, 11000); val32 = ehci_readl(ehci, portsc); } while (++retry_cnt < RETRY_CNT_LIMIT && !(val32 & PORT_CONNECT)); if (retry_cnt >= RETRY_CNT_LIMIT) dev_info(&pdev->dev, "%s: retry_cnt = %d, portsc = 0x%x\n", __func__, retry_cnt, val32); }