static int omap_ohci_bus_suspend(struct usb_hcd *hcd) { struct ohci_omap_clock_defs *ohci_clocks; int ret = 0; ohci_clocks = (struct ohci_omap_clock_defs *) (((char *)hcd_to_ohci(hcd)) + sizeof(struct ohci_hcd)); if (!ohci_clocks->suspended) { ret = ohci_bus_suspend(hcd); if (ret) return ret; mdelay(8); /* MSTANDBY assertion delayed by ~8ms */ ohci_context_save(); clk_disable(ohci_clocks->usbhost_ick_clk); clk_disable(ohci_clocks->usbhost1_48m_fck_clk); clk_disable(ohci_clocks->usbhost2_120m_fck_clk); clk_disable(ohci_clocks->usbtll_ick_clk); clk_disable(ohci_clocks->usbtll_fck_clk); ohci_clocks->suspended = 1; clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); } return ret; }
static int stm_ohci_bus_suspend(struct usb_hcd *hcd) { dgb_print("\n"); ohci_bus_suspend(hcd); usb_root_hub_lost_power(hcd->self.root_hub); return 0; }
/** * \internal * \brief Manages timeouts and actions based on SOF events * - UHC user notification * - SOF user notification */ static void uhd_sof_interrupt(void *pointer) { UNUSED(pointer); /* Manage a delay to enter in suspend */ if (uhd_suspend_start) { if (--uhd_suspend_start == 0) { ohci_bus_suspend(); uhd_sleep_mode(UHD_STATE_SUSPEND); } return; // Abort SOF events } /* Manage a delay to exit of suspend */ if (uhd_resume_start) { if (--uhd_resume_start == 0) { // Notify the UHC uhc_notify_resume(); uhd_sleep_mode(UHD_STATE_IDLE); } return; // Abort SOF events } /* Notify the UHC. */ uhc_notify_sof(false); /* Notify the user application. */ UHC_SOF_EVENT(); }
static int ohci_omap3_bus_suspend(struct usb_hcd *hcd) { struct device *dev = hcd->self.controller; struct omap_hwmod *oh; int ret = 0; dev_dbg(dev, "ohci_omap3_bus_suspend\n"); ret = ohci_bus_suspend(hcd); /* Delay required so that after ohci suspend * smart stand by can be set in the driver. * required for power mangament */ msleep(5); if (ret != 0) { dev_dbg(dev, "ohci_omap3_bus_suspend failed %d\n", ret); return ret; } oh = omap_hwmod_lookup(USBHS_OHCI_HWMODNAME); omap_hwmod_enable_ioring_wakeup(oh); if (dev->parent) pm_runtime_put_sync(dev->parent); return ret; }
static int exynos_ohci_bus_suspend(struct usb_hcd *hcd) { int ret; ohci_exynos_set_clock(1); ret = ohci_bus_suspend(hcd); ohci_exynos_set_clock(0); return ret; }
static int exynos_ohci_bus_suspend(struct usb_hcd *hcd) { int ret; ret = ohci_bus_suspend(hcd); /* Decrease pm_count that was increased at s5p_ehci_resume func. */ pm_runtime_put_noidle(hcd->self.controller); return ret; }
static int ohci_omap3_bus_suspend(struct usb_hcd *hcd) { struct device *dev = hcd->self.controller; struct ohci_hcd_omap_platform_data *pdata; #ifndef CONFIG_USB_OOBWAKE struct omap_hwmod *oh; #endif int ret = 0; dev_dbg(dev, "ohci_omap3_bus_suspend\n"); ret = ohci_bus_suspend(hcd); /* Delay required so that after ohci suspend * smart stand by can be set in the driver. * required for power mangament */ msleep(5); if (ret != 0) { dev_dbg(dev, "ohci_omap3_bus_suspend failed %d\n", ret); return ret; } disable_irq(hcd->irq); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); #ifndef CONFIG_USB_OOBWAKE oh = omap_hwmod_lookup(USBHS_OHCI_HWMODNAME); if (oh) omap_hwmod_enable_ioring_wakeup(oh); #endif if (dev->parent) pm_runtime_put_sync(dev->parent); /* Disable Any External Transceiver */ pdata = dev->platform_data; if (pdata->ohci_phy_suspend) pdata->ohci_phy_suspend(1); return ret; }
static int omap_ohci_bus_suspend(struct usb_hcd *hcd) { int res; int ret = 0; struct ohci_hcd *ohci = hcd_to_ohci(hcd); #if defined(CONFIG_ARCH_OMAP34XX) struct omap_usb_config *config = hcd->self.controller->platform_data; #endif ret = ohci_bus_suspend(hcd); if (ret) return ret; mdelay(8); /* MSTANDBY assertion is delayed by ~8ms */ #if defined(CONFIG_ARCH_OMAP34XX) if (config->usbhost_standby_status) res = config->usbhost_standby_status(); #endif if (res == 0) { printk(KERN_ERR "ohci: suspend failed!\n"); ohci_bus_resume(hcd); return -EBUSY ; } /* go ahead turn off clock */ clk_disable(clk_get(NULL, "usbtll_fck")); clk_disable(clk_get(NULL, "usbhost_120m_fck")); clk_disable(clk_get(NULL, "usbhost_48m_fck")); /* the omap usb host auto-idle is not fully functional, * manually enable/disable usbtll_ick during * the suspend/resume time. */ clk_disable(clk_get(NULL, "usbtll_ick")); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; return ret; }
static int omap_ohci_bus_suspend(struct usb_hcd *hcd) { struct ohci_omap_clock_defs *ohci_clocks; int ret = 0; u32 uhh_sysconfig; ohci_clocks = (struct ohci_omap_clock_defs *) (((char *)hcd_to_ohci(hcd)) + sizeof(struct ohci_hcd)); if (!ohci_clocks->suspended) { ret = ohci_bus_suspend(hcd); if (ret) return ret; mdelay(8); /* MSTANDBY assertion delayed by ~8ms */ /* Need to set ForceStandby,ForceIdle here * else the domain may not be able to transition * back during clk_enable if there was a pending event. */ uhh_sysconfig = omap_readl(OMAP_UHH_SYSCONFIG); uhh_sysconfig &= ~(3 << OMAP_UHH_SYSCONFIG_MIDLEMODE_SHIFT); uhh_sysconfig &= ~(3 << OMAP_UHH_SYSCONFIG_SIDLEMODE_SHIFT); omap_writel(uhh_sysconfig, OMAP_UHH_SYSCONFIG); ohci_context_save(); clk_disable(ohci_clocks->usbhost_ick_clk); clk_disable(ohci_clocks->usbhost2_120m_fck_clk); clk_disable(ohci_clocks->usbhost1_48m_fck_clk); clk_disable(ohci_clocks->usbtll_ick_clk); clk_disable(ohci_clocks->usbtll_fck_clk); ohci_clocks->suspended = 1; clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); } return ret; }
static int ohci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int i, changed = 0, length = 1; int can_suspend; unsigned long flags; can_suspend = device_may_wakeup(&hcd->self.root_hub->dev); spin_lock_irqsave (&ohci->lock, flags); /* handle autosuspended root: finish resuming before * letting khubd or root hub timer see state changes. */ if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER || !HC_IS_RUNNING(hcd->state))) { can_suspend = 0; goto done; } /* undocumented erratum seen on at least rev D */ if ((ohci->flags & OHCI_QUIRK_AMD756) && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) { ohci_warn (ohci, "bogus NDP, rereads as NDP=%d\n", ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP); /* retry later; "should not happen" */ goto done; } /* init status */ if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC)) buf [0] = changed = 1; else buf [0] = 0; if (ohci->num_ports > 7) { buf [1] = 0; length++; } /* look at each port */ for (i = 0; i < ohci->num_ports; i++) { u32 status = roothub_portstatus (ohci, i); /* can't autosuspend with active ports */ if ((status & RH_PS_PES) && !(status & RH_PS_PSS)) can_suspend = 0; if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) { changed = 1; if (i < 7) buf [0] |= 1 << (i + 1); else buf [1] |= 1 << (i - 7); continue; } } /* after root hub changes, stop polling after debouncing * for a while and maybe kicking in autosuspend */ if (changed) { ohci->next_statechange = jiffies + STATECHANGE_DELAY; can_suspend = 0; } else if (time_before (jiffies, ohci->next_statechange)) { can_suspend = 0; } else { #ifdef CONFIG_PM can_suspend = can_suspend && !ohci->ed_rm_list && ((OHCI_CTRL_HCFS | OHCI_SCHED_ENABLES) & ohci->hc_control) == OHCI_USB_OPER; #endif if (hcd->uses_new_polling) { hcd->poll_rh = 0; /* use INTR_RHSC iff INTR_RD won't apply */ if (!can_suspend) ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); } } done: spin_unlock_irqrestore (&ohci->lock, flags); #ifdef CONFIG_PM /* save power by autosuspending idle root hubs; * INTR_RD wakes us when there's work */ if (can_suspend && usb_trylock_device (hcd->self.root_hub) == 0) { ohci_vdbg (ohci, "autosuspend\n"); (void) ohci_bus_suspend (hcd); usb_unlock_device (hcd->self.root_hub); } #endif return changed ? length : 0; }
static int ohci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int i, changed = 0, length = 1; int can_suspend = hcd->can_wakeup; unsigned long flags; spin_lock_irqsave (&ohci->lock, flags); /* handle autosuspended root: finish resuming before * letting khubd or root hub timer see state changes. */ if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER || !HC_IS_RUNNING(hcd->state))) { can_suspend = 0; goto done; } /* undocumented erratum seen on at least rev D */ if ((ohci->flags & OHCI_QUIRK_AMD756) && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) { ohci_warn (ohci, "bogus NDP, rereads as NDP=%d\n", ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP); /* retry later; "should not happen" */ goto done; } /* init status */ if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC)) buf [0] = changed = 1; else buf [0] = 0; if (ohci->num_ports > 7) { buf [1] = 0; length++; } /* look at each port */ for (i = 0; i < ohci->num_ports; i++) { u32 status = roothub_portstatus (ohci, i); if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) { changed = 1; if (i < 7) buf [0] |= 1 << (i + 1); else buf [1] |= 1 << (i - 7); continue; } /* can suspend if no ports are enabled; or if all all * enabled ports are suspended AND remote wakeup is on. */ if (!(status & RH_PS_CCS)) continue; if ((status & RH_PS_PSS) && hcd->remote_wakeup) continue; can_suspend = 0; } done: spin_unlock_irqrestore (&ohci->lock, flags); #ifdef CONFIG_PM /* save power by suspending idle root hubs; * INTR_RD wakes us when there's work */ if (can_suspend && !changed && !ohci->ed_rm_list && ((OHCI_CTRL_HCFS | OHCI_SCHED_ENABLES) & ohci->hc_control) == OHCI_USB_OPER && time_after (jiffies, ohci->next_statechange) && usb_trylock_device (hcd->self.root_hub) == 0 ) { ohci_vdbg (ohci, "autosuspend\n"); (void) ohci_bus_suspend (hcd); usb_unlock_device (hcd->self.root_hub); } #endif return changed ? length : 0; }