diff options
author | Dinh Nguyen <r00091@freescale.com> | 2009-09-16 11:31:02 -0500 |
---|---|---|
committer | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-02-12 17:19:13 +0100 |
commit | be490e5431216bef29eefedde905a45e22d05477 (patch) | |
tree | a6a2da8cc60df6b2616b887ee3b7136ad14a3f56 /drivers/usb | |
parent | aca8630a75798e500a0bc64c05346a4089b2fda7 (diff) |
usb: add ehci otg support
Add OTG support to ehci host controllers
Signed-off-by: Dinh Nguyen <r00091@freescale.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/hub.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 31 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 5 |
3 files changed, 44 insertions, 0 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 71f86c60d83c..5acf9757b09a 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1160,6 +1160,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) return -E2BIG; } + /* With OTG enabled, suspending root hub results in gadget not + * working because gadget uses the same root hub. We disable + * this feature when OTG is selected. + */ +#if defined(CONFIG_PM) && defined(CONFIG_USB_EHCI_ARC_OTG) + hdev->autosuspend_disabled = 1; +#endif + #ifdef CONFIG_USB_OTG_BLACKLIST_HUB if (hdev->parent) { dev_warn(&intf->dev, "ignoring external hub\n"); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index f46ad27c9a90..615d263c57c1 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -549,6 +549,37 @@ ehci_hub_descriptor ( desc->wHubCharacteristics = cpu_to_le16(temp); } +#ifdef CONFIG_USB_OTG +static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 status; + + if (!port) + return -EINVAL; + port--; + + /* start port reset before HNP protocol time out */ + status = readl(&ehci->regs->port_status[port]); + if (!(status & PORT_CONNECT)) + return -ENODEV; + + /* khubd will finish the reset later */ + if (ehci_is_TDI(ehci)) + writel(PORT_RESET | (status & ~(PORT_CSC | PORT_PEC + | PORT_OCC)), &ehci->regs->port_status[port]); + else + writel(PORT_RESET, &ehci->regs->port_status[port]); + + return 0; +} +#else +static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) +{ + return 0; +} +#endif /* CONFIG_USB_OTG */ + /*-------------------------------------------------------------------------*/ static int ehci_hub_control ( diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2bfff30f4704..5947f6c19567 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -138,6 +138,11 @@ struct ehci_hcd { /* one per controller */ u8 sbrn; /* packed release number */ + /* + * OTG controllers and transceivers need software interaction; + * other external transceivers should be software-transparent + */ + struct otg_transceiver *transceiver; /* irq statistics */ #ifdef EHCI_STATS struct ehci_stats stats; |