示例#1
0
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;
}
示例#2
0
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;
}
示例#3
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();
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#10
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;
	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;
}
示例#11
0
文件: ohci-hub.c 项目: ena30/snake-os
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;
}