static int ehci_arc_resume(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); u32 tmp; struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; dbg("%s pdev=0x%p pdata=0x%p ehci=0x%p hcd=0x%p\n", __FUNCTION__, pdev, pdata, ehci, hcd); vdbg("%s ehci->regs=0x%p hcd->regs=0x%p usbmode=0x%x\n", __FUNCTION__, ehci->regs, hcd->regs, pdata->usbmode); tmp = USBMODE_CM_HOST; if (ehci_big_endian_mmio(ehci)) tmp |= USBMODE_BE; ehci_writel(ehci, tmp, (u32 *)pdata->usbmode); memcpy(ehci->regs, (void *)&usb_ehci_regs, sizeof(struct ehci_regs)); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); hcd->state = HC_STATE_RUNNING; pdev->dev.power.power_state = PMSG_ON; tmp = ehci_readl(ehci, &ehci->regs->command); tmp |= CMD_RUN; ehci_writel(ehci, tmp, &ehci->regs->command); fsl_platform_set_vbus_power(pdata, 1); usb_hcd_resume_root_hub(hcd); return 0; }
static irqreturn_t tegra_ehci_irq(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); struct ehci_hcd *ehci = hcd_to_ehci(hcd); irqreturn_t irq_status; spin_lock(&ehci->lock); irq_status = tegra_usb_phy_irq(tegra->phy); if (irq_status == IRQ_NONE) { spin_unlock(&ehci->lock); return irq_status; } if (tegra_usb_phy_pmc_wakeup(tegra->phy)) { ehci_dbg(ehci, "pmc wakeup detected\n"); usb_hcd_resume_root_hub(hcd); spin_unlock(&ehci->lock); return irq_status; } spin_unlock(&ehci->lock); EHCI_DBG("%s() cmd = 0x%x, int_sts = 0x%x, portsc = 0x%x\n", __func__, ehci_readl(ehci, &ehci->regs->command), ehci_readl(ehci, &ehci->regs->status), ehci_readl(ehci, &ehci->regs->port_status[0])); irq_status = ehci_irq(hcd); if (ehci->controller_remote_wakeup) { ehci->controller_remote_wakeup = false; tegra_usb_phy_pre_resume(tegra->phy, true); tegra->port_resuming = 1; } return irq_status; }
static int ehci_mid_runtime_resume_host(struct intel_mid_otg_xceiv *iotg) { int retval; struct device *dev; struct pci_dev *pci_dev; struct usb_hcd *hcd; if (iotg == NULL) return -EINVAL; if (ehci_otg_driver.driver.pm == NULL) return -EINVAL; dev = iotg->otg.dev; pci_dev = to_pci_dev(dev); hcd = pci_get_drvdata(pci_dev); retval = ehci_otg_driver.driver.pm->runtime_resume(dev); if (retval) dev_warn(dev, "runtime suspend failed\n"); /* Workaround: EHCI currently unable to deal with interrupt * when remote wakeup happens, * so a manuallly root-hub resuming is performed here. */ if (!retval) { dev_dbg(dev, "resume root hub\n"); usb_hcd_resume_root_hub(hcd); } return retval; }
static void usb3_ehci_dock_in_work_handler(struct work_struct *w) { struct ehci_hcd *ehci = hcd_to_ehci (usb3_ehci_handle); printk(KERN_INFO "%s: usb resume root hub\n",__func__); usb_hcd_resume_root_hub(usb3_ehci_handle); }
static int ehci_msm_pm_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); int ret; u32 portsc; dev_dbg(dev, "ehci-msm PM resume\n"); if (!hcd->rh_registered) return 0; /* Notify OTG to bring hw out of LPM before restoring wakeup flags */ ret = usb_phy_set_suspend(phy, 0); if (ret) return ret; ehci_resume(hcd, false); portsc = readl_relaxed(USB_PORTSC); portsc &= ~PORT_RWC_BITS; portsc |= PORT_RESUME; writel_relaxed(portsc, USB_PORTSC); /* Resume root-hub to handle USB event if any else initiate LPM again */ usb_hcd_resume_root_hub(hcd); return ret; }
static int ehci_fsl_drv_resume(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); u32 tmp; struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; /* set host mode */ tmp = USBMODE_CM_HOST | (pdata->es ? USBMODE_ES : 0); ehci_writel(ehci, tmp, hcd->regs + FSL_SOC_USB_USBMODE); /* restore EHCI registers */ ehci_writel(ehci, usb_ehci_regs.command, &ehci->regs->command); ehci_writel(ehci, usb_ehci_regs.intr_enable, &ehci->regs->intr_enable); ehci_writel(ehci, usb_ehci_regs.frame_index, &ehci->regs->frame_index); ehci_writel(ehci, usb_ehci_regs.segment, &ehci->regs->segment); ehci_writel(ehci, usb_ehci_regs.frame_list, &ehci->regs->frame_list); ehci_writel(ehci, usb_ehci_regs.async_next, &ehci->regs->async_next); ehci_writel(ehci, usb_ehci_regs.configured_flag, &ehci->regs->configured_flag); ehci_writel(ehci, usb_ehci_regs.frame_list, &ehci->regs->frame_list); ehci_writel(ehci, usb_ehci_portsc, &ehci->regs->port_status[0]); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); hcd->state = HC_STATE_RUNNING; pdev->dev.power.power_state = PMSG_ON; tmp = ehci_readl(ehci, &ehci->regs->command); tmp |= CMD_RUN; ehci_writel(ehci, tmp, &ehci->regs->command); usb_hcd_resume_root_hub(hcd); return 0; }
static void compliance_mode_recovery(unsigned long arg) { struct xhci_hcd *xhci; struct usb_hcd *hcd; u32 temp; int i; xhci = (struct xhci_hcd *)arg; for (i = 0; i < xhci->num_usb3_ports; i++) { temp = readl(xhci->usb3_ports[i]); if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { /* * Compliance Mode Detected. Letting USB Core * handle the Warm Reset */ xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "Compliance mode detected->port %d", i + 1); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "Attempting compliance mode recovery"); hcd = xhci->shared_hcd; if (hcd->state == HC_STATE_SUSPENDED) usb_hcd_resume_root_hub(hcd); usb_hcd_poll_rh_status(hcd); } } if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1)) mod_timer(&xhci->comp_mode_recovery_timer, jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); }
static int mxhci_hsic_resume(struct mxhci_hsic_hcd *mxhci) { struct usb_hcd *hcd = hsic_to_hcd(mxhci); int ret; unsigned long flags; if (!mxhci->in_lpm) { dev_dbg(mxhci->dev, "%s called in !in_lpm\n", __func__); return 0; } pm_stay_awake(mxhci->dev); /* enable force-on mode for periph_on */ clk_set_flags(mxhci->system_clk, CLKFLAG_RETAIN_PERIPH); if (mxhci->bus_perf_client) { mxhci->bus_vote = true; queue_work(mxhci->wq, &mxhci->bus_vote_w); } spin_lock_irqsave(&mxhci->wakeup_lock, flags); if (mxhci->wakeup_irq_enabled) { disable_irq_wake(mxhci->wakeup_irq); disable_irq_nosync(mxhci->wakeup_irq); mxhci->wakeup_irq_enabled = 0; } if (mxhci->pm_usage_cnt) { mxhci->pm_usage_cnt = 0; pm_runtime_put_noidle(mxhci->dev); } spin_unlock_irqrestore(&mxhci->wakeup_lock, flags); ret = regulator_set_voltage(mxhci->hsic_vddcx, mxhci->vdd_low_vol_level, mxhci->vdd_high_vol_level); if (ret < 0) dev_err(mxhci->dev, "unable to set nominal vddcx voltage (no VDD MIN)\n"); clk_prepare_enable(mxhci->system_clk); clk_prepare_enable(mxhci->cal_clk); clk_prepare_enable(mxhci->hsic_clk); clk_prepare_enable(mxhci->utmi_clk); clk_prepare_enable(mxhci->core_clk); if (mxhci->wakeup_irq) usb_hcd_resume_root_hub(hcd); mxhci->in_lpm = 0; dev_dbg(mxhci->dev, "HSIC-USB exited from low power mode\n"); xhci_dbg_log_event(&dbg_hsic, NULL, "Controller resumed", 0); return 0; }
static int ehci_fsl_drv_resume(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); u32 tmp; struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; printk(KERN_INFO "USB Host resumed\n"); pr_debug("%s('%s'): suspend=%d already_suspended=%d\n", __func__, pdata->name, pdata->suspended, pdata->already_suspended); /* * If the controller was already suspended at suspend time, * then don't resume it now. */ if (pdata->already_suspended) { pr_debug("already suspended, leaving early\n"); pdata->already_suspended = 0; return 0; } if (!pdata->suspended) { pr_debug("not suspended, leaving early\n"); return 0; } pdata->suspended = 0; pr_debug("%s resuming...\n", __func__); /* set host mode */ fsl_platform_set_host_mode(hcd); /* restore EHCI registers */ ehci_writel(ehci, pdata->pm_command, &ehci->regs->command); ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable); ehci_writel(ehci, pdata->pm_frame_index, &ehci->regs->frame_index); ehci_writel(ehci, pdata->pm_segment, &ehci->regs->segment); ehci_writel(ehci, pdata->pm_frame_list, &ehci->regs->frame_list); ehci_writel(ehci, pdata->pm_async_next, &ehci->regs->async_next); ehci_writel(ehci, pdata->pm_configured_flag, &ehci->regs->configured_flag); ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); hcd->state = HC_STATE_RUNNING; pdev->dev.power.power_state = PMSG_ON; tmp = ehci_readl(ehci, &ehci->regs->command); tmp |= CMD_RUN; ehci_writel(ehci, tmp, &ehci->regs->command); usb_hcd_resume_root_hub(hcd); return 0; }
static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned long flags; int status = 0; spin_lock_irqsave(&uhci->lock, flags); uhci_scan_schedule(uhci); if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead) goto done; uhci_check_ports(uhci); status = get_hub_status_data(uhci, buf); switch (uhci->rh_state) { case UHCI_RH_SUSPENDED: if (status || uhci->resuming_ports) { status = 1; usb_hcd_resume_root_hub(hcd); } break; case UHCI_RH_AUTO_STOPPED: if (status) wakeup_rh(uhci); break; case UHCI_RH_RUNNING: if (!any_ports_active(uhci)) { uhci->rh_state = UHCI_RH_RUNNING_NODEVS; uhci->auto_stop_time = jiffies + HZ; } break; case UHCI_RH_RUNNING_NODEVS: if (any_ports_active(uhci)) uhci->rh_state = UHCI_RH_RUNNING; else if (time_after_eq(jiffies, uhci->auto_stop_time) && !uhci->wait_for_hp) suspend_rh(uhci, UHCI_RH_AUTO_STOPPED); break; default: break; } done: spin_unlock_irqrestore(&uhci->lock, flags); return status; }
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; } }
static irqreturn_t ehci_hcd_omap_hack_handler(int irq, void *dev) { struct ehci_hcd_omap *omap = dev_get_drvdata(dev); struct ehci_hcd *ehci = omap->ehci; struct usb_hcd *hcd = ehci_to_hcd(ehci); /* resume root hub? */ usb_hcd_resume_root_hub(hcd); return IRQ_HANDLED; }
static int str9100_ohci_resume(struct platform_device *pdev) { struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev)); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; pdev->power.power_state = PMSG_ON; usb_hcd_resume_root_hub(dev_get_drvdata(pdev)); return 0; }
/* * Work thread function for handling the USB power sequence. * * This work thread is created to avoid the pre-emption from the ISR context. * USB Power Rail and Vbus are controlled based on the USB cable connection. * USB Power rail function and VBUS control function cannot be called from ISR * as NvRmPmuSetVoltage() uses I2C driver, that waits on semaphore * during the I2C transaction this will cause the pre-emption if called in ISR. */ static void tegra_ehci_irq_work(struct work_struct* irq_work) { struct ehci_hcd *ehci = container_of(irq_work, struct ehci_hcd, irq_work); struct usb_hcd *hcd = ehci_to_hcd(ehci); struct tegra_hcd_platform_data *pdata; u32 status; bool kick_rhub = false; pdata = hcd->self.controller->platform_data; #ifdef CONFIG_USB_OTG_UTILS if (pdata->otg_mode && ehci->transceiver) { if (ehci->transceiver->state == OTG_STATE_A_HOST) { if (!ehci->host_reinited) { ehci->host_reinited = 1; tegra_ehci_power_up(hcd); if (hcd->state == HC_STATE_SUSPENDED) kick_rhub = true; tegra_ehci_restart(hcd); } } else if (ehci->transceiver->state == OTG_STATE_A_SUSPEND) { if (ehci->host_reinited) { /* indicate hcd flags, that hardware is not accessible now */ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); ehci_halt(ehci); tegra_ehci_power_down(hcd); ehci->transceiver->state = OTG_STATE_UNDEFINED; ehci->host_reinited = 0; } } } else #endif { if (pdata->id_detect == ID_PIN_CABLE_ID) { /* read otgsc register for ID pin status change */ status = readl(hcd->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); /* Check pin status and enable/disable the power */ if (status & TEGRA_USB_ID_PIN_STATUS) { tegra_ehci_power_down(hcd); } else { tegra_ehci_power_up(hcd); if (hcd->state == HC_STATE_SUSPENDED) kick_rhub = true; } } } if (kick_rhub) { hcd->state = HC_STATE_SUSPENDED; usb_hcd_resume_root_hub(hcd); } }
static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned long flags; int status = 0; spin_lock_irqsave(&uhci->lock, flags); uhci_scan_schedule(uhci); if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) goto done; uhci_check_ports(uhci); status = get_hub_status_data(uhci, buf); switch (uhci->rh_state) { case UHCI_RH_SUSPENDING: case UHCI_RH_SUSPENDED: /* if port change, ask to be resumed */ if (status) usb_hcd_resume_root_hub(hcd); break; case UHCI_RH_AUTO_STOPPED: /* if port change, auto start */ if (status) wakeup_rh(uhci); break; case UHCI_RH_RUNNING: /* are any devices attached? */ if (!any_ports_active(uhci)) { uhci->rh_state = UHCI_RH_RUNNING_NODEVS; uhci->auto_stop_time = jiffies + HZ; } break; case UHCI_RH_RUNNING_NODEVS: /* auto-stop if nothing connected for 1 second */ if (any_ports_active(uhci)) uhci->rh_state = UHCI_RH_RUNNING; else if (time_after_eq(jiffies, uhci->auto_stop_time)) suspend_rh(uhci, UHCI_RH_AUTO_STOPPED); break; default: break; } done: spin_unlock_irqrestore(&uhci->lock, flags); return status; }
static int ohci_omap_resume(struct platform_device *dev) { struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; omap_ohci_clock_power(1); dev->dev.power.power_state = PMSG_ON; usb_hcd_resume_root_hub(platform_get_drvdata(dev)); return 0; }
static int ohci_hcd_s3c2410_drv_resume(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; s3c2410_start_hc(pdev, hcd); pdev->dev.power.power_state = PMSG_ON; usb_hcd_resume_root_hub(hcd); return 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; } }
static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_regs __iomem *hw = ehci->regs; struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); u32 val; #ifndef CONFIG_ARCH_TEGRA_2x_SOC /* Fence read for coherency of AHB master intiated writes */ if (tegra->phy->instance == 0) readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); else if (tegra->phy->instance == 1) readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); else if (tegra->phy->instance == 2) readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); #endif if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && (tegra->ehci->has_hostpc)) { /* check if there is any remote wake event */ if (tegra_usb_phy_is_remotewake_detected(tegra->phy)) { usb_hcd_resume_root_hub(hcd); } } if (tegra->phy->hotplug) { spin_lock(&ehci->lock); val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); if ((val & TEGRA_USB_PHY_CLK_VALID_INT_STS)) { val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB | TEGRA_USB_PHY_CLK_VALID_INT_STS; writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); val = readl(&hw->status); if (!(val & STS_PCD)) { spin_unlock(&ehci->lock); return 0; } val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET); val &= ~(TEGRA_USB_PORTSC1_WKCN | PORT_RWC_BITS); writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); } spin_unlock(&ehci->lock); } return ehci_irq(hcd); }
static int s5p_ehci_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; struct usb_hcd *hcd = platform_get_drvdata(pdev); struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd); int rc = 0; if (dev->power.is_suspended) return 0; dev_dbg(dev, "%s\n", __func__); if (s5p_ehci->phy) { struct usb_phy *phy = s5p_ehci->phy; if (s5p_ehci->post_lpa_resume) usb_phy_init(phy); pm_runtime_get_sync(phy->dev); } else if (pdata && pdata->phy_resume) { rc = pdata->phy_resume(pdev, USB_PHY_TYPE_HOST); s5p_ehci->post_lpa_resume = !!rc; } if (s5p_ehci->post_lpa_resume) s5p_ehci_configurate(hcd); ehci_resume(hcd, false); /* * REVISIT: in case of LPA bus won't be resumed, so we do it here. * Alternatively, we can try to setup HC in such a way that it starts * to sense connections. In this case, root hub will be resumed from * interrupt (ehci_irq()). */ if (s5p_ehci->post_lpa_resume) usb_hcd_resume_root_hub(hcd); s5p_ehci->post_lpa_resume = 0; return 0; }
/** * The hcd operation need to be done during the wakeup irq */ void fsl_usb_recover_hcd(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); u32 cmd = 0; set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* After receive remote wakeup signaling. Must restore * CMDRUN bit in 20ms to keep port status. */ cmd = ehci_readl(ehci, &ehci->regs->command); if (!(cmd & CMD_RUN)) { ehci_writel(ehci, ehci->command, &ehci->regs->command); /* Resume root hub here? */ usb_hcd_resume_root_hub(hcd); } /* disable all interrupt, will re-enable in resume */ ehci_writel(ehci, 0, &ehci->regs->intr_enable); }
static irqreturn_t msm_ehci_dock_connect_irq(int irq, void *data) { const struct msm_usb_host_platform_data *pdata; struct msm_hcd *mhcd = data; struct usb_hcd *hcd = mhcd_to_hcd(mhcd); pdata = mhcd->dev->platform_data; if (atomic_read(&mhcd->in_lpm)) usb_hcd_resume_root_hub(hcd); if (irq_read_line(pdata->dock_connect_irq)) { dev_dbg(mhcd->dev, "%s:Dock removed disable vbus\n", __func__); msm_ehci_vbus_power(mhcd, 0); } else { dev_dbg(mhcd->dev, "%s:Dock connected enable vbus\n", __func__); msm_ehci_vbus_power(mhcd, 1); } return IRQ_HANDLED; }
static int ehci_msm_pm_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); int ret; dev_dbg(dev, "ehci-msm PM resume\n"); if (!hcd->rh_registered) return 0; /* Notify OTG to bring hw out of LPM before restoring wakeup flags */ ret = usb_phy_set_suspend(phy, 0); if (ret) return ret; ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd)); /* Resume root-hub to handle USB event if any else initiate LPM again */ usb_hcd_resume_root_hub(hcd); return ret; }
/** Initializes the DWC_otg controller and its root hub and prepares it for host * mode operation. Activates the root port. Returns 0 on success and a negative * error code on failure. */ int hcd_start(struct usb_hcd *hcd) { dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); struct usb_bus *bus; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n"); bus = hcd_to_bus(hcd); hcd->state = HC_STATE_RUNNING; if (dwc_otg_hcd_start(dwc_otg_hcd, &hcd_fops)) { return 0; } /* Initialize and connect root hub if one is not already attached */ if (bus->root_hub) { DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n"); /* Inform the HUB driver to resume. */ usb_hcd_resume_root_hub(hcd); } return 0; }
static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_regs __iomem *hw = ehci->regs; struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); u32 val; if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && (tegra->ehci->has_hostpc)) { /* check if there is any remote wake event */ if (tegra_usb_phy_is_remotewake_detected(tegra->phy)) { spin_lock (&ehci->lock); usb_hcd_resume_root_hub(hcd); spin_unlock (&ehci->lock); } } if (tegra->hotplug) { spin_lock(&ehci->lock); val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); if ((val & TEGRA_USB_PHY_CLK_VALID_INT_STS)) { val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB | TEGRA_USB_PHY_CLK_VALID_INT_STS; writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET); val &= ~TEGRA_USB_PORTSC1_WKCN; writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); val = readl(&hw->status); if (!(val & STS_PCD)) { spin_unlock(&ehci->lock); return 0; } } spin_unlock(&ehci->lock); } return ehci_irq(hcd); }
/* * start xHC (not bus-specific) * * This is called when the machine transition from S3/S4 mode. * */ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) { u32 command, temp = 0, status; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; int retval = 0; bool comp_timer_running = false; if (!hcd->state) return 0; /* Wait a bit if either of the roothubs need to settle from the * transition into bus suspend. */ if (time_before(jiffies, xhci->bus_state[0].next_statechange) || time_before(jiffies, xhci->bus_state[1].next_statechange)) msleep(100); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); spin_lock_irq(&xhci->lock); if (xhci->quirks & XHCI_RESET_ON_RESUME) hibernated = true; if (!hibernated) { /* step 1: restore register */ xhci_restore_registers(xhci); /* step 2: initialize command ring buffer */ xhci_set_cmd_ring_deq(xhci); /* step 3: restore state and start state*/ /* step 3: set CRS flag */ command = readl(&xhci->op_regs->command); command |= CMD_CRS; writel(command, &xhci->op_regs->command); if (xhci_handshake(&xhci->op_regs->status, STS_RESTORE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC restore state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } temp = readl(&xhci->op_regs->status); } /* If restore operation fails, re-initialize the HC during resume */ if ((temp & STS_SRE) || hibernated) { if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !(xhci_all_ports_seen_u0(xhci))) { del_timer_sync(&xhci->comp_mode_recovery_timer); xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "Compliance Mode Recovery Timer deleted!"); } /* Let the USB core know _both_ roothubs lost power. */ usb_root_hub_lost_power(xhci->main_hcd->self.root_hub); usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub); xhci_dbg(xhci, "Stop HCD\n"); xhci_halt(xhci); xhci_reset(xhci); spin_unlock_irq(&xhci->lock); xhci_cleanup_msix(xhci); xhci_dbg(xhci, "// Disabling event ring interrupts\n"); temp = readl(&xhci->op_regs->status); writel(temp & ~STS_EINT, &xhci->op_regs->status); temp = readl(&xhci->ir_set->irq_pending); writel(ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending); xhci_print_ir_set(xhci, 0); xhci_dbg(xhci, "cleaning up memory\n"); xhci_mem_cleanup(xhci); xhci_dbg(xhci, "xhci_stop completed - status = %x\n", readl(&xhci->op_regs->status)); /* USB core calls the PCI reinit and start functions twice: * first with the primary HCD, and then with the secondary HCD. * If we don't do the same, the host will never be started. */ if (!usb_hcd_is_primary_hcd(hcd)) secondary_hcd = hcd; else secondary_hcd = xhci->shared_hcd; xhci_dbg(xhci, "Initialize the xhci_hcd\n"); retval = xhci_init(hcd->primary_hcd); if (retval) return retval; comp_timer_running = true; xhci_dbg(xhci, "Start the primary HCD\n"); retval = xhci_run(hcd->primary_hcd); if (!retval) { xhci_dbg(xhci, "Start the secondary HCD\n"); retval = xhci_run(secondary_hcd); } hcd->state = HC_STATE_SUSPENDED; xhci->shared_hcd->state = HC_STATE_SUSPENDED; goto done; } /* step 4: set Run/Stop bit */ command = readl(&xhci->op_regs->command); command |= CMD_RUN; writel(command, &xhci->op_regs->command); xhci_handshake(&xhci->op_regs->status, STS_HALT, 0, 250 * 1000); /* step 5: walk topology and initialize portsc, * portpmsc and portli */ /* this is done in bus_resume */ /* step 6: restart each of the previously * Running endpoints by ringing their doorbells */ spin_unlock_irq(&xhci->lock); done: if (retval == 0) { /* Resume root hubs only when have pending events. */ status = readl(&xhci->op_regs->status); if (status & STS_EINT) { usb_hcd_resume_root_hub(hcd); usb_hcd_resume_root_hub(xhci->shared_hcd); } } /* * If system is subject to the Quirk, Compliance Mode Timer needs to * be re-initialized Always after a system resume. Ports are subject * to suffer the Compliance Mode issue again. It doesn't matter if * ports have entered previously to U0 before system's suspension. */ if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running) compliance_mode_recovery_timer_init(xhci); /* Re-enable port polling. */ xhci_dbg(xhci, "%s: starting port polling.\n", __func__); set_bit(HCD_FLAG_POLL_RH, &hcd->flags); usb_hcd_poll_rh_status(hcd); set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); usb_hcd_poll_rh_status(xhci->shared_hcd); return retval; }
static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_regs __iomem *hw = ehci->regs; struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); u32 val; irqreturn_t irq_status; bool pmc_remote_wakeup = false; /* Fence read for coherency of AHB master intiated writes */ if (tegra->phy->instance == 0) readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID)); else if (tegra->phy->instance == 1) readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID)); else if (tegra->phy->instance == 2) readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID)); if ((tegra->phy->usb_phy_type == TEGRA_USB_PHY_TYPE_UTMIP) && (tegra->ehci->has_hostpc)) { /* check if there is any remote wake event */ if (tegra_usb_phy_is_remotewake_detected(tegra->phy)) { pmc_remote_wakeup = true; spin_lock (&ehci->lock); usb_hcd_resume_root_hub(hcd); spin_unlock (&ehci->lock); } } if (tegra->phy->hotplug) { spin_lock(&ehci->lock); val = readl(hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET); if ((val & TEGRA_USB_PHY_CLK_VALID_INT_STS)) { val &= ~TEGRA_USB_PHY_CLK_VALID_INT_ENB | TEGRA_USB_PHY_CLK_VALID_INT_STS; writel(val , (hcd->regs + TEGRA_USB_SUSP_CTRL_OFFSET)); val = readl(&hw->status); if (!(val & STS_PCD)) { spin_unlock(&ehci->lock); return 0; } val = readl(hcd->regs + TEGRA_USB_PORTSC1_OFFSET); val &= ~(TEGRA_USB_PORTSC1_WKCN | PORT_RWC_BITS); writel(val , (hcd->regs + TEGRA_USB_PORTSC1_OFFSET)); } spin_unlock(&ehci->lock); } irq_status = ehci_irq(hcd); if (pmc_remote_wakeup) { ehci->controller_remote_wakeup = false; } if (ehci->controller_remote_wakeup) { ehci->controller_remote_wakeup = false; /* disable interrupts */ ehci_writel(ehci, 0, &ehci->regs->intr_enable); tegra_usb_phy_preresume(tegra->phy, true); tegra->port_resuming = 1; } return irq_status; }
static int msm_hsic_resume(struct msm_hsic_hcd *mehci) { struct usb_hcd *hcd = hsic_to_hcd(mehci); int cnt = 0, ret; unsigned temp; int min_vol, max_vol; if (!atomic_read(&mehci->in_lpm)) { dev_dbg(mehci->dev, "%s called in !in_lpm\n", __func__); return 0; } if (mehci->wakeup_irq_enabled) { disable_irq_wake(mehci->wakeup_irq); disable_irq_nosync(mehci->wakeup_irq); mehci->wakeup_irq_enabled = 0; } wake_lock(&mehci->wlock); if (mehci->bus_perf_client && debug_bus_voting_enabled) { mehci->bus_vote = true; queue_work(ehci_wq, &mehci->bus_vote_w); } min_vol = vdd_val[mehci->vdd_type][VDD_MIN]; max_vol = vdd_val[mehci->vdd_type][VDD_MAX]; ret = regulator_set_voltage(mehci->hsic_vddcx, min_vol, max_vol); if (ret < 0) dev_err(mehci->dev, "unable to set nominal vddcx voltage (no VDD MIN)\n"); clk_prepare_enable(mehci->core_clk); clk_prepare_enable(mehci->phy_clk); clk_prepare_enable(mehci->cal_clk); clk_prepare_enable(mehci->ahb_clk); temp = readl_relaxed(USB_USBCMD); temp &= ~ASYNC_INTR_CTRL; temp &= ~ULPI_STP_CTRL; writel_relaxed(temp, USB_USBCMD); if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD)) goto skip_phy_resume; temp = readl_relaxed(USB_PORTSC); temp &= ~(PORT_RWC_BITS | PORTSC_PHCD); writel_relaxed(temp, USB_PORTSC); while (cnt < PHY_RESUME_TIMEOUT_USEC) { if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD) && (readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_SYNC_STATE)) break; udelay(1); cnt++; } if (cnt >= PHY_RESUME_TIMEOUT_USEC) { /* * This is a fatal error. Reset the link and * PHY to make hsic working. */ dev_err(mehci->dev, "Unable to resume USB. Reset the hsic\n"); msm_hsic_config_gpios(mehci, 0); msm_hsic_reset(mehci); } skip_phy_resume: usb_hcd_resume_root_hub(hcd); atomic_set(&mehci->in_lpm, 0); if (mehci->async_int) { mehci->async_int = false; pm_runtime_put_noidle(mehci->dev); enable_irq(hcd->irq); } if (atomic_read(&mehci->pm_usage_cnt)) { atomic_set(&mehci->pm_usage_cnt, 0); pm_runtime_put_noidle(mehci->dev); } dev_dbg(mehci->dev, "HSIC-USB exited from low power mode\n"); return 0; }
static int ohci_pci_resume (struct usb_hcd *hcd) { set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); usb_hcd_resume_root_hub(hcd); return 0; }
static int msm_ehci_resume(struct msm_hcd *mhcd) { struct usb_hcd *hcd = mhcd_to_hcd(mhcd); unsigned long timeout; unsigned temp; int ret; if (!atomic_read(&mhcd->in_lpm)) { dev_dbg(mhcd->dev, "%s called in !in_lpm\n", __func__); return 0; } //ASUS_BSP+++ BennyCheng "implement ehci3 phy power collapse mode" mutex_lock(&mhcd->ehci_mutex); //ASUS_BSP--- BennyCheng "implement ehci3 phy power collapse mode" if (mhcd->pmic_gpio_dp_irq_enabled) { disable_irq_wake(mhcd->pmic_gpio_dp_irq); disable_irq_nosync(mhcd->pmic_gpio_dp_irq); mhcd->pmic_gpio_dp_irq_enabled = 0; } wake_lock(&mhcd->wlock); /* Vote for TCXO when waking up the phy */ ret = msm_xo_mode_vote(mhcd->xo_handle, MSM_XO_MODE_ON); if (ret) dev_err(mhcd->dev, "%s failed to vote for " "TCXO D0 buffer%d\n", __func__, ret); clk_prepare_enable(mhcd->core_clk); clk_prepare_enable(mhcd->iface_clk); msm_ehci_config_vddcx(mhcd, 1); //ASUS_BSP+++ BennyCheng "implement ehci3 phy power collapse mode" if (mhcd->lpm_flags & PHY_PWR_COLLAPSED) { msm_ehci_ldo_enable(mhcd, 1); mhcd->lpm_flags &= ~PHY_PWR_COLLAPSED; } //ASUS_BSP--- BennyCheng "implement ehci3 phy power collapse mode" temp = readl_relaxed(USB_USBCMD); temp &= ~ASYNC_INTR_CTRL; temp &= ~ULPI_STP_CTRL; writel_relaxed(temp, USB_USBCMD); if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD)) goto skip_phy_resume; temp = readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD; writel_relaxed(temp, USB_PORTSC); timeout = jiffies + usecs_to_jiffies(PHY_RESUME_TIMEOUT_USEC); while ((readl_relaxed(USB_PORTSC) & PORTSC_PHCD) || !(readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_SYNC_STATE)) { if (time_after(jiffies, timeout)) { /*This is a fatal error. Reset the link and PHY*/ dev_err(mhcd->dev, "Unable to resume USB. Resetting the h/w\n"); msm_hsusb_reset(mhcd); break; } udelay(1); } skip_phy_resume: usb_hcd_resume_root_hub(hcd); atomic_set(&mhcd->in_lpm, 0); if (mhcd->async_int) { mhcd->async_int = false; pm_runtime_put_noidle(mhcd->dev); enable_irq(hcd->irq); } if (atomic_read(&mhcd->pm_usage_cnt)) { atomic_set(&mhcd->pm_usage_cnt, 0); pm_runtime_put_noidle(mhcd->dev); } //ASUS_BSP+++ BennyCheng "implement ehci3 phy power collapse mode" mutex_unlock(&mhcd->ehci_mutex); //ASUS_BSP--- BennyCheng "implement ehci3 phy power collapse mode" dev_info(mhcd->dev, "EHCI USB exited from low power mode\n"); return 0; }