Пример #1
0
static int ohci_omap_resume(struct device *dev, u32 level)
{
	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
	int		status = 0;

	if (level != RESUME_POWER_ON)
		return 0;

	switch (dev->power.power_state) {
	case 0:
		break;
	case 4:
		if (time_before(jiffies, ohci->next_statechange))
			msleep(5);
		ohci->next_statechange = jiffies;
		omap_ohci_clock_power(1);
		/* FALLTHROUGH */
	default:
		dev_dbg(dev, "resume from %d\n", dev->power.power_state);
#ifdef	CONFIG_USB_SUSPEND
		/* get extra cleanup even if remote wakeup isn't in use */
		status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
#else
		down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
		status = ohci_hub_resume(ohci_to_hcd(ohci));
		up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
#endif
		if (status == 0)
			dev->power.power_state = 0;
		break;
	}
	return status;
}
Пример #2
0
static int ohci_omap_suspend(struct device *dev, u32 state, u32 level)
{
	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
	int		status = -EINVAL;

	if (state <= dev->power.power_state)
		return 0;

	dev_dbg(dev, "suspend to %d\n", state);
	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
	status = ohci_hub_suspend(ohci_to_hcd(ohci));
	if (status == 0) {
		if (state >= 4) {
			/* power off + reset */
			OTG_SYSCON_2_REG &= ~UHOST_EN;
			ohci_to_hcd(ohci)->self.root_hub->state =
					USB_STATE_SUSPENDED;
			state = 4;
		}
		ohci_to_hcd(ohci)->state = HCD_STATE_SUSPENDED;
		dev->power.power_state = state;
	}
	up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
	return status;
}
Пример #3
0
static int ohci_omap_suspend(struct device *dev, u32 state, u32 level)
{
	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
	int		status = -EINVAL;

	if (level != SUSPEND_POWER_DOWN)
		return 0;
	if (state <= dev->power.power_state)
		return 0;

	dev_dbg(dev, "suspend to %d\n", state);
	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
	status = ohci_hub_suspend(ohci_to_hcd(ohci));
	if (status == 0) {
		if (state >= 4) {
			omap_ohci_clock_power(0);
			ohci_to_hcd(ohci)->self.root_hub->state =
					USB_STATE_SUSPENDED;
			state = 4;
		}
		ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
		dev->power.power_state = state;
	}
	up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
	return status;
}
Пример #4
0
static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message)
{
	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_bus_suspend(ohci_to_hcd(ohci));
	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
	dev->dev.power.power_state = PMSG_SUSPEND;
	return 0;
}
Пример #5
0
static void ohci_hcd_init (struct ohci_hcd *ohci)
{
	ohci->next_statechange = jiffies;
	spin_lock_init (&ohci->lock);
	INIT_LIST_HEAD (&ohci->pending);
	INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
}
Пример #6
0
int ohci_power(void *ohci, int is_on)
{
	struct ohci_hcd *ohcip = (struct ohci_hcd *)ohci;
	int port;
	int temp;

	temp = roothub_a(ohcip);

	/* If NoPowerSwitching is true, just return */
	if (temp & RH_A_NPS) {
		return 0;
	}

	/* If port switched, switch each port */
	if (temp & RH_A_PSM) {
		for (port = ohcip->num_ports; port > 0; ) {
			(void) ohci_hub_control(ohci_to_hcd(ohcip),
									is_on ? SetPortFeature : ClearPortFeature,
									USB_PORT_FEAT_POWER,
									port--, NULL, 0);
		}
	}
	/* Else use Global Power */
	else {
		temp = roothub_status(ohcip);
		if (is_on) {
			temp |= RH_HS_LPSC;	 /* SetGlobalPower */
		}
		else {
			temp |= RH_HS_LPS;	 /* ClearGlobalPower */
		}
		ohci_writel(ohcip, temp, &ohcip->regs->roothub.status);
	}
	return 0;
}
Пример #7
0
static void ohci_hcd_omap3_shutdown(struct platform_device *pdev)
{
    struct ohci_hcd_omap3 *omap = platform_get_drvdata(pdev);
    struct usb_hcd *hcd = ohci_to_hcd(omap->ohci);

    if (hcd->driver->shutdown)
        hcd->driver->shutdown(hcd);
}
Пример #8
0
static int ohci_mem_init (struct ohci_hcd *ohci)
{
	ohci->td_cache = dma_pool_create ("ohci_td",
		ohci_to_hcd(ohci)->self.controller,
		sizeof (struct td),
		32 /* byte alignment */,
		0 /* no page-crossing issues */);
	if (!ohci->td_cache)
		return -ENOMEM;
	ohci->ed_cache = dma_pool_create ("ohci_ed",
		ohci_to_hcd(ohci)->self.controller,
		sizeof (struct ed),
		16 /* byte alignment */,
		0 /* no page-crossing issues */);
	if (!ohci->ed_cache) {
		dma_pool_destroy (ohci->td_cache);
		return -ENOMEM;
	}
	return 0;
}
Пример #9
0
static void sb800_prefetch(struct ohci_hcd *ohci, int on)
{
	struct pci_dev *pdev;
	u16 misc;

	pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller);
	pci_read_config_word(pdev, 0x50, &misc);
	if (on == 0)
		pci_write_config_word(pdev, 0x50, misc & 0xfcff);
	else
		pci_write_config_word(pdev, 0x50, misc | 0x0300);
}
Пример #10
0
static void start_hnp(struct ohci_hcd *ohci)
{
	const unsigned	port = ohci_to_hcd(ohci)->self.otg_port - 1;
	unsigned long	flags;

	otg_start_hnp(ohci->transceiver);

	local_irq_save(flags);
	ohci->transceiver->state = OTG_STATE_A_SUSPEND;
	writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]);
	OTG_CTRL_REG &= ~OTG_A_BUSREQ;
	local_irq_restore(flags);
}
Пример #11
0
static int str9100_ohci_suspend(struct platform_device *pdev, pm_message_t message)
{
	struct ohci_hcd	*ohci = hcd_to_ohci(platform_get_drvdata(pdev));

	if (time_before(jiffies, ohci->next_statechange))
		msleep(5);
	ohci->next_statechange = jiffies;

	str9100_ohci_clock_power(0);
	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
	pdev->power.power_state = PMSG_SUSPEND;
	return 0;
}
Пример #12
0
static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg)
{
	struct device *dev = &pdev->dev;
	struct ohci_hcd	*ohci = hcd_to_ohci(platform_get_drvdata(pdev));

	if (time_before(jiffies, ohci->next_statechange))
		msleep(5);
	ohci->next_statechange = jiffies;

	sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0);
	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
	return 0;
}
Пример #13
0
/**
 * ohci_hcd_omap3_remove - shutdown processing for OHCI HCDs
 * @pdev: USB Host Controller being removed
 *
 * Reverses the effect of ohci_hcd_omap3_probe(), first invoking
 * the HCD's stop() method.  It is always called from a thread
 * context, normally "rmmod", "apmd", or something similar.
 */
static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev)
{
    struct ohci_hcd_omap3 *omap = platform_get_drvdata(pdev);
    struct usb_hcd *hcd = ohci_to_hcd(omap->ohci);

    usb_remove_hcd(hcd);
    omap3_stop_ohci(omap, hcd);
    iounmap(hcd->regs);
    iounmap(omap->tll_base);
    iounmap(omap->uhh_base);
    usb_put_hcd(hcd);
    kfree(omap);

    return 0;
}
Пример #14
0
static int __devinit
ohci_ppc_of_start(struct usb_hcd *hcd)
{
	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
	int		ret;

	if ((ret = ohci_init(ohci)) < 0)
		return ret;

	if ((ret = ohci_run(ohci)) < 0) {
		err("can't start %s", ohci_to_hcd(ohci)->self.bus_name);
		ohci_stop(hcd);
		return ret;
	}

	return 0;
}
Пример #15
0
static void start_hnp(struct ohci_hcd *ohci)
{
	struct usb_hcd *hcd = ohci_to_hcd(ohci);
	const unsigned	port = hcd->self.otg_port - 1;
	unsigned long	flags;
	u32 l;

	otg_start_hnp(hcd->phy->otg);

	local_irq_save(flags);
	hcd->phy->state = OTG_STATE_A_SUSPEND;
	writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]);
	l = omap_readl(OTG_CTRL);
	l &= ~OTG_A_BUSREQ;
	omap_writel(l, OTG_CTRL);
	local_irq_restore(flags);
}
Пример #16
0
static int __devinit str9100_ohci_start(struct usb_hcd *hcd)
{
	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
	int ret;

	//ohci->regs = hcd->regs;
	//ohci->fminterval = 0x27782edf;
	if ((ret = ohci_init(ohci)) < 0)
		return ret;

	if ((ret = ohci_run(ohci)) < 0) {
		err("can't start %s", ohci_to_hcd(ohci)->self.bus_name);
		ohci_stop(hcd);
		return ret;
	}

	return 0;
}
Пример #17
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;
}
Пример #18
0
static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
{
	struct pxaohci_platform_data *inf;
	uint32_t uhccoms;

	inf = dev->platform_data;

	if (cpu_is_pxa3xx())
		pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);

	if (inf->exit)
		inf->exit(dev);

	pxa27x_reset_hc(ohci);

	/* Host Controller Reset */
	uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01;
	__raw_writel(uhccoms, ohci->mmio_base + UHCCOMS);
	udelay(10);

	clk_disable(ohci->clk);
}
Пример #19
0
static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
{
	int retval = 0;
	struct pxaohci_platform_data *inf;
	uint32_t uhchr;

	inf = dev->platform_data;

	clk_enable(ohci->clk);

	pxa27x_reset_hc(ohci);

	uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
	__raw_writel(uhchr, ohci->mmio_base + UHCHR);

	while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
		cpu_relax();

	pxa27x_setup_hc(ohci, inf);

	if (inf->init)
		retval = inf->init(dev);

	if (retval < 0)
		return retval;

	if (cpu_is_pxa3xx())
		pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);

	uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);

	/* Clear any OTG Pin Hold */
	pxa27x_clear_otgph();
	return 0;
}
static inline void remove_ohci_sys_file(struct ohci_hcd *ohci)
{
	device_remove_file(ohci_to_hcd(ohci)->self.controller,
			&dev_attr_ohci_power);
}
static inline int create_ohci_sys_file(struct ohci_hcd *ohci)
{
	return device_create_file(ohci_to_hcd(ohci)->self.controller,
			&dev_attr_ohci_power);
}
Пример #22
0
static int ohci_omap_init(struct usb_hcd *hcd)
{
	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
	struct omap_usb_config	*config = hcd->self.controller->platform_data;
	int			need_transceiver = (config->otg != 0);
	int			ret;

	dev_dbg(hcd->self.controller, "starting USB Controller\n");

	if (config->otg) {
		ohci_to_hcd(ohci)->self.otg_port = config->otg;
		/* default/minimum OTG power budget:  8 mA */
		ohci_to_hcd(ohci)->power_budget = 8;
	}

	/* boards can use OTG transceivers in non-OTG modes */
	need_transceiver = need_transceiver
			|| machine_is_omap_h2() || machine_is_omap_h3();

	if (cpu_is_omap16xx())
		ocpi_enable();

#ifdef	CONFIG_ARCH_OMAP_OTG
	if (need_transceiver) {
		ohci->transceiver = otg_get_transceiver();
		if (ohci->transceiver) {
			int	status = otg_set_host(ohci->transceiver,
						&ohci_to_hcd(ohci)->self);
			dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n",
					ohci->transceiver->label, status);
			if (status) {
				if (ohci->transceiver)
					put_device(ohci->transceiver->dev);
				return status;
			}
		} else {
			dev_err(hcd->self.controller, "can't find transceiver\n");
			return -ENODEV;
		}
	}
#endif

	omap_ohci_clock_power(1);

	if (cpu_is_omap1510()) {
		omap_1510_local_bus_power(1);
		omap_1510_local_bus_init();
	}

	if ((ret = ohci_init(ohci)) < 0)
		return ret;

	/* board-specific power switching and overcurrent support */
	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
		u32	rh = roothub_a (ohci);

		/* power switching (ganged by default) */
		rh &= ~RH_A_NPS;

		/* TPS2045 switch for internal transceiver (port 1) */
		if (machine_is_omap_osk()) {
			ohci_to_hcd(ohci)->power_budget = 250;

			rh &= ~RH_A_NOCP;

			/* gpio9 for overcurrent detction */
			omap_cfg_reg(W8_1610_GPIO9);
			omap_request_gpio(9);
			omap_set_gpio_direction(9, 1 /* IN */);

			/* for paranoia's sake:  disable USB.PUEN */
			omap_cfg_reg(W4_USB_HIGHZ);
		}
		ohci_writel(ohci, rh, &ohci->regs->roothub.a);
		distrust_firmware = 0;
	} else if (machine_is_nokia770()) {
		/* We require a self-powered hub, which should have
		 * plenty of power. */
		ohci_to_hcd(ohci)->power_budget = 0;
	}

	/* FIXME khubd hub requests should manage power switching */
	omap_ohci_transceiver_power(1);

	/* board init will have already handled HMC and mux setup.
	 * any external transceiver should already be initialized
	 * too, so all configured ports use the right signaling now.
	 */

	return 0;
}
Пример #23
0
static int ohci_omap_reset(struct usb_hcd *hcd)
{
	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
	struct omap_usb_config	*config = dev_get_platdata(hcd->self.controller);
	int			need_transceiver = (config->otg != 0);
	int			ret;

	dev_dbg(hcd->self.controller, "starting USB Controller\n");

	if (config->otg) {
		hcd->self.otg_port = config->otg;
		/* default/minimum OTG power budget:  8 mA */
		hcd->power_budget = 8;
	}

	/* boards can use OTG transceivers in non-OTG modes */
	need_transceiver = need_transceiver
			|| machine_is_omap_h2() || machine_is_omap_h3();

	/* XXX OMAP16xx only */
	if (config->ocpi_enable)
		config->ocpi_enable();

#ifdef	CONFIG_USB_OTG
	if (need_transceiver) {
		hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2);
		if (!IS_ERR_OR_NULL(hcd->phy)) {
			int	status = otg_set_host(hcd->phy->otg,
						&ohci_to_hcd(ohci)->self);
			dev_dbg(hcd->self.controller, "init %s phy, status %d\n",
					hcd->phy->label, status);
			if (status) {
				usb_put_phy(hcd->phy);
				return status;
			}
		} else {
			dev_err(hcd->self.controller, "can't find phy\n");
			return -ENODEV;
		}
		ohci->start_hnp = start_hnp;
	}
#endif

	omap_ohci_clock_power(1);

	if (cpu_is_omap15xx()) {
		omap_1510_local_bus_power(1);
		omap_1510_local_bus_init();
	}

	ret = ohci_setup(hcd);
	if (ret < 0)
		return ret;

	if (config->otg || config->rwc) {
		ohci->hc_control = OHCI_CTRL_RWC;
		writel(OHCI_CTRL_RWC, &ohci->regs->control);
	}

	/* board-specific power switching and overcurrent support */
	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
		u32	rh = roothub_a (ohci);

		/* power switching (ganged by default) */
		rh &= ~RH_A_NPS;

		/* TPS2045 switch for internal transceiver (port 1) */
		if (machine_is_omap_osk()) {
			ohci_to_hcd(ohci)->power_budget = 250;

			rh &= ~RH_A_NOCP;

			/* gpio9 for overcurrent detction */
			omap_cfg_reg(W8_1610_GPIO9);
			gpio_request(9, "OHCI overcurrent");
			gpio_direction_input(9);

			/* for paranoia's sake:  disable USB.PUEN */
			omap_cfg_reg(W4_USB_HIGHZ);
		}
		ohci_writel(ohci, rh, &ohci->regs->roothub.a);
		ohci->flags &= ~OHCI_QUIRK_HUB_POWER;
	} else if (machine_is_nokia770()) {
		/* We require a self-powered hub, which should have
		 * plenty of power. */
		ohci_to_hcd(ohci)->power_budget = 0;
	}

	/* FIXME khubd hub requests should manage power switching */
	omap_ohci_transceiver_power(1);

	/* board init will have already handled HMC and mux setup.
	 * any external transceiver should already be initialized
	 * too, so all configured ports use the right signaling now.
	 */

	return 0;
}
Пример #24
0
	kfree (urb_priv);
}

/*-------------------------------------------------------------------------*/

/*
 * URB goes back to driver, and isn't reissued.
 * It's completely gone from HC data structures.
 * PRECONDITION:  ohci lock held, irqs blocked.
 */
static void
finish_urb(struct ohci_hcd *ohci, struct urb *urb, int status)
__releases(ohci->lock)
__acquires(ohci->lock)
{
	struct device *dev = ohci_to_hcd(ohci)->self.controller;
	struct usb_host_endpoint *ep = urb->ep;
	struct urb_priv *urb_priv;

	// ASSERT (urb->hcpriv != 0);

 restart:
	urb_free_priv (ohci, urb->hcpriv);
	urb->hcpriv = NULL;
	if (likely(status == -EINPROGRESS))
		status = 0;

	switch (usb_pipetype (urb->pipe)) {
	case PIPE_ISOCHRONOUS:
		ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
		if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
Пример #25
0
static int ohci_bus_suspend (struct usb_hcd *hcd)
{
	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
	int			status = 0;
	unsigned long		flags;

	spin_lock_irqsave (&ohci->lock, flags);

	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
		spin_unlock_irqrestore (&ohci->lock, flags);
		return -ESHUTDOWN;
	}

	ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
	switch (ohci->hc_control & OHCI_CTRL_HCFS) {
	case OHCI_USB_RESUME:
		ohci_dbg (ohci, "resume/suspend?\n");
		ohci->hc_control &= ~OHCI_CTRL_HCFS;
		ohci->hc_control |= OHCI_USB_RESET;
		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
		(void) ohci_readl (ohci, &ohci->regs->control);
		/* FALL THROUGH */
	case OHCI_USB_RESET:
		status = -EBUSY;
		ohci_dbg (ohci, "needs reinit!\n");
		goto done;
	case OHCI_USB_SUSPEND:
		ohci_dbg (ohci, "already suspended\n");
		goto done;
	}
	ohci_dbg (ohci, "suspend root hub\n");

	/* First stop any processing */
	if (ohci->hc_control & OHCI_SCHED_ENABLES) {
		int		limit;

		ohci->hc_control &= ~OHCI_SCHED_ENABLES;
		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
		ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
		ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrstatus);

		/* sched disables take effect on the next frame,
		 * then the last WDH could take 6+ msec
		 */
		ohci_dbg (ohci, "stopping schedules ...\n");
		limit = 2000;
		while (limit > 0) {
			udelay (250);
			limit =- 250;
			if (ohci_readl (ohci, &ohci->regs->intrstatus)
					& OHCI_INTR_SF)
				break;
		}
		dl_done_list (ohci, NULL);
		mdelay (7);
	}
	dl_done_list (ohci, NULL);
	finish_unlinks (ohci, ohci_frame_no(ohci), NULL);
	ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
			&ohci->regs->intrstatus);

	/* maybe resume can wake root hub */
	if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev))
		ohci->hc_control |= OHCI_CTRL_RWE;
	else
		ohci->hc_control &= ~OHCI_CTRL_RWE;

	/* Suspend hub ... this is the "global (to this bus) suspend" mode,
	 * which doesn't imply ports will first be individually suspended.
	 */
	ohci->hc_control &= ~OHCI_CTRL_HCFS;
	ohci->hc_control |= OHCI_USB_SUSPEND;
	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
	(void) ohci_readl (ohci, &ohci->regs->control);

	/* no resumes until devices finish suspending */
	ohci->next_statechange = jiffies + msecs_to_jiffies (5);

	/* no timer polling */
	hcd->poll_rh = 0;

done:
	/* external suspend vs self autosuspend ... same effect */
	if (status == 0)
		usb_hcd_suspend_root_hub(hcd);
	spin_unlock_irqrestore (&ohci->lock, flags);
	return status;
}
Пример #26
0
static int ohci_omap_init(struct usb_hcd *hcd)
{
	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
	struct omap_usb_config	*config = hcd->self.controller->platform_data;
	int			need_transceiver = (config->otg != 0);
	int			ret;

	dev_dbg(hcd->self.controller, "starting USB Controller\n");

	if (config->otg) {
		ohci_to_hcd(ohci)->self.otg_port = config->otg;
		/*                                         */
		ohci_to_hcd(ohci)->power_budget = 8;
	}

	/*                                                  */
	need_transceiver = need_transceiver
			|| machine_is_omap_h2() || machine_is_omap_h3();

	if (cpu_is_omap16xx())
		ocpi_enable();

#ifdef	CONFIG_USB_OTG
	if (need_transceiver) {
		ohci->transceiver = usb_get_transceiver();
		if (ohci->transceiver) {
			int	status = otg_set_host(ohci->transceiver->otg,
						&ohci_to_hcd(ohci)->self);
			dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n",
					ohci->transceiver->label, status);
			if (status) {
				if (ohci->transceiver)
					put_device(ohci->transceiver->dev);
				return status;
			}
		} else {
			dev_err(hcd->self.controller, "can't find transceiver\n");
			return -ENODEV;
		}
		ohci->start_hnp = start_hnp;
	}
#endif

	omap_ohci_clock_power(1);

	if (cpu_is_omap15xx()) {
		omap_1510_local_bus_power(1);
		omap_1510_local_bus_init();
	}

	if ((ret = ohci_init(ohci)) < 0)
		return ret;

	/*                                                        */
	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
		u32	rh = roothub_a (ohci);

		/*                                     */
		rh &= ~RH_A_NPS;

		/*                                                  */
		if (machine_is_omap_osk()) {
			ohci_to_hcd(ohci)->power_budget = 250;

			rh &= ~RH_A_NOCP;

			/*                                */
			omap_cfg_reg(W8_1610_GPIO9);
			gpio_request(9, "OHCI overcurrent");
			gpio_direction_input(9);

			/*                                        */
			omap_cfg_reg(W4_USB_HIGHZ);
		}
		ohci_writel(ohci, rh, &ohci->regs->roothub.a);
		ohci->flags &= ~OHCI_QUIRK_HUB_POWER;
	} else if (machine_is_nokia770()) {
		/*                                                 
                      */
		ohci_to_hcd(ohci)->power_budget = 0;
	}

	/*                                                        */
	omap_ohci_transceiver_power(1);

	/*                                                        
                                                          
                                                             
  */

	return 0;
}
Пример #27
0
static int omap_start_hc(struct ohci_hcd *ohci, struct platform_device *pdev)
{
	struct omap_usb_config	*config = pdev->dev.platform_data;
	int			need_transceiver = (config->otg != 0);

	dev_dbg(&pdev->dev, "starting USB Controller\n");

	if (config->otg) {
		ohci_to_hcd(ohci)->self.otg_port = config->otg;
		/* default/minimum OTG power budget:  8 mA */
		ohci->power_budget = 8;
	}

	/* boards can use OTG transceivers in non-OTG modes */
	need_transceiver = need_transceiver
			|| machine_is_omap_h2();

	if (cpu_is_omap16xx())
		ocpi_enable();

#ifdef	CONFIG_ARCH_OMAP_OTG
	if (need_transceiver) {
		ohci->transceiver = otg_get_transceiver();
		if (ohci->transceiver) {
			int	status = otg_set_host(ohci->transceiver,
						&ohci_to_hcd(ohci)->self);
			dev_dbg(&pdev->dev, "init %s transceiver, status %d\n",
					ohci->transceiver->label, status);
			if (status) {
				if (ohci->transceiver)
					put_device(ohci->transceiver->dev);
				return status;
			}
		} else {
			dev_err(&pdev->dev, "can't find transceiver\n");
			return -ENODEV;
		}
	}
#endif

	if (machine_is_omap_osk()) {
		omap_request_gpio(9);
		omap_set_gpio_direction(9, 1);
		omap_set_gpio_dataout(9, 1);
	}

	omap_ohci_clock_power(1);

	omap_ohci_transceiver_power(1);

	if (cpu_is_omap1510()) {
		omap_1510_local_bus_power(1);
		omap_1510_local_bus_init();
	}

	/* board init will have already handled HMC and mux setup.
	 * any external transceiver should already be initialized
	 * too, so all configured ports use the right signaling now.
	 */

	return 0;
}