diff options
Diffstat (limited to 'drivers/usb/host')
69 files changed, 8264 insertions, 1238 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 4263d011392..5be0326aae3 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -29,15 +29,6 @@ if USB_XHCI_HCD config USB_XHCI_PLATFORM tristate -config USB_XHCI_HCD_DEBUGGING - bool "Debugging for the xHCI host controller" - ---help--- - Say 'Y' to turn on debugging for the xHCI host controller driver. - This will spew debugging output, even in interrupt context. - This should only be used for debugging xHCI driver bugs. - - If unsure, say N. - endif # USB_XHCI_HCD config USB_EHCI_HCD @@ -113,12 +104,6 @@ config USB_EHCI_HCD_PMC_MSP Enables support for the onchip USB controller on the PMC_MSP7100 Family SoC's. If unsure, say N. -config USB_EHCI_BIG_ENDIAN_MMIO - bool - -config USB_EHCI_BIG_ENDIAN_DESC - bool - config XPS_USB_HCD_XILINX bool "Use Xilinx usb host EHCI controller core" depends on (PPC32 || MICROBLAZE) @@ -148,13 +133,11 @@ config USB_EHCI_MXC config USB_EHCI_HCD_OMAP tristate "EHCI support for OMAP3 and later chips" depends on ARCH_OMAP + select NOP_USB_XCEIV default y ---help--- Enables support for the on-chip EHCI controller on OMAP3 and later chips. - If your system uses a PHY on the USB port, you will need to - enable USB_PHY and the appropriate PHY driver as well. Most - boards need the NOP_USB_XCEIV PHY driver. config USB_EHCI_HCD_ORION tristate "Support for Marvell EBU on-chip EHCI USB controller" @@ -186,7 +169,6 @@ config USB_EHCI_HCD_AT91 config USB_EHCI_MSM tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" depends on ARCH_MSM - depends on USB_PHY select USB_EHCI_ROOT_HUB_TT select USB_MSM_OTG ---help--- @@ -354,6 +336,18 @@ config USB_FUSBH200_HCD To compile this driver as a module, choose M here: the module will be called fusbh200-hcd. +config USB_FOTG210_HCD + tristate "FOTG210 HCD support" + depends on USB + default N + ---help--- + Faraday FOTG210 is an OTG controller which can be configured as + an USB2.0 host. It is designed to meet USB2.0 EHCI specification + with minor modification. + + To compile this driver as a module, choose M here: the + module will be called fotg210-hcd. + config USB_OHCI_HCD tristate "OHCI HCD (USB 1.1) support" select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 @@ -497,20 +491,6 @@ config USB_OCTEON_OHCI controller. It is needed for low-speed USB 1.0 device support. All CN6XXX based chips with USB are supported. - -config USB_OHCI_BIG_ENDIAN_DESC - bool - default n - -config USB_OHCI_BIG_ENDIAN_MMIO - bool - default n - -config USB_OHCI_LITTLE_ENDIAN - bool - default n if STB03xxx || PPC_MPC52xx - default y - endif # USB_OHCI_HCD config USB_UHCI_HCD @@ -710,3 +690,20 @@ config USB_HCD_SSB for ehci and ohci. If unsure, say N. + +config USB_HCD_TEST_MODE + bool "HCD test mode support" + ---help--- + Say 'Y' to enable additional software test modes that may be + supported by the host controller drivers. + + One such test mode is the Embedded High-speed Host Electrical Test + (EHSET) for EHCI host controller hardware, specifically the "Single + Step Set Feature" test. Typically this will be enabled for On-the-Go + or embedded hosts that need to undergo USB-IF compliance testing with + the aid of special testing hardware. In the future, this may expand + to include other tests that require support from a HCD driver. + + This option is of interest only to developers who need to validate + their USB hardware designs. It is not needed for normal use. If + unsure, say N. diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index bea71127b15..50b0041c09a 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -4,6 +4,9 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG +# tell define_trace.h where to find the xhci trace header +CFLAGS_xhci-trace.o := -I$(src) + isp1760-y := isp1760-hcd.o isp1760-if.o fhci-y := fhci-hcd.o fhci-hub.o fhci-q.o @@ -13,6 +16,7 @@ fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o xhci-hcd-y := xhci.o xhci-mem.o xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o +xhci-hcd-y += xhci-trace.o xhci-hcd-$(CONFIG_PCI) += xhci-pci.o ifneq ($(CONFIG_USB_XHCI_PLATFORM), ) @@ -58,3 +62,4 @@ obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o obj-$(CONFIG_USB_FUSBH200_HCD) += fusbh200-hcd.o +obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 5429d2645bb..aa5b603f393 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -18,7 +18,7 @@ /* this file is part of ehci-hcd.c */ -#ifdef DEBUG +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) /* check the values in the HCSPARAMS register * (host controller _Structural_ parameters) @@ -62,7 +62,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {} #endif -#ifdef DEBUG +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) /* check the values in the HCCPARAMS register * (host controller _Capability_ parameters) @@ -101,7 +101,7 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {} #endif -#ifdef DEBUG +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) static void __maybe_unused dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) @@ -301,7 +301,7 @@ static inline int __maybe_unused dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status) { return 0; } -#endif /* DEBUG */ +#endif /* DEBUG || CONFIG_DYNAMIC_DEBUG */ /* functions have the "wrong" filename when they're output... */ #define dbg_status(ehci, label, status) { \ @@ -336,7 +336,6 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { } static int debug_async_open(struct inode *, struct file *); static int debug_periodic_open(struct inode *, struct file *); static int debug_registers_open(struct inode *, struct file *); -static int debug_async_open(struct inode *, struct file *); static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*); static int debug_close(struct inode *, struct file *); diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index bd831ec06dc..947b009009f 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -57,7 +57,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, pr_debug("initializing FSL-SOC USB Controller\n"); /* Need platform data for setup */ - pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data; + pdata = (struct fsl_usb2_platform_data *)dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "No platform data for %s.\n", dev_name(&pdev->dev)); @@ -190,7 +190,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, static void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev) { - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); if (!IS_ERR_OR_NULL(hcd->phy)) { otg_set_host(hcd->phy->otg, NULL); @@ -218,7 +218,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd->regs; struct device *dev = hcd->self.controller; - struct fsl_usb2_platform_data *pdata = dev->platform_data; + struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); if (pdata->controller_ver < 0) { dev_warn(hcd->self.controller, "Could not get controller version\n"); @@ -291,7 +291,7 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) struct fsl_usb2_platform_data *pdata; void __iomem *non_ehci = hcd->regs; - pdata = hcd->self.controller->platform_data; + pdata = dev_get_platdata(hcd->self.controller); if (pdata->have_sysif_regs) { /* @@ -363,7 +363,7 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) struct device *dev; dev = hcd->self.controller; - pdata = hcd->self.controller->platform_data; + pdata = dev_get_platdata(hcd->self.controller); ehci->big_endian_desc = pdata->big_endian_desc; ehci->big_endian_mmio = pdata->big_endian_mmio; @@ -415,10 +415,10 @@ static int ehci_fsl_mpc512x_drv_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct fsl_usb2_platform_data *pdata = dev->platform_data; + struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); u32 tmp; -#ifdef DEBUG +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) u32 mode = ehci_readl(ehci, hcd->regs + FSL_SOC_USB_USBMODE); mode &= USBMODE_CM_MASK; tmp = ehci_readl(ehci, hcd->regs + 0x140); /* usbcmd */ @@ -484,7 +484,7 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct fsl_usb2_platform_data *pdata = dev->platform_data; + struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); u32 tmp; dev_dbg(dev, "suspend=%d already_suspended=%d\n", @@ -669,7 +669,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_USB2 | HCD_MEMORY, + .flags = HCD_USB2 | HCD_MEMORY | HCD_BH, /* * basic lifecycle operations diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index a77bd8dc33f..b52a66ce92e 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -43,7 +43,7 @@ static const struct hc_driver ehci_grlib_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, + .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, /* * basic lifecycle operations @@ -167,15 +167,6 @@ static int ehci_hcd_grlib_remove(struct platform_device *op) } -static void ehci_hcd_grlib_shutdown(struct platform_device *op) -{ - struct usb_hcd *hcd = platform_get_drvdata(op); - - if (hcd->driver->shutdown) - hcd->driver->shutdown(hcd); -} - - static const struct of_device_id ehci_hcd_grlib_of_match[] = { { .name = "GAISLER_EHCI", @@ -191,7 +182,7 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_grlib_of_match); static struct platform_driver ehci_grlib_driver = { .probe = ehci_hcd_grlib_probe, .remove = ehci_hcd_grlib_remove, - .shutdown = ehci_hcd_grlib_shutdown, + .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "grlib-ehci", .owner = THIS_MODULE, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 7abf1ce3a67..5d6022f30eb 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -440,14 +440,6 @@ static void ehci_stop (struct usb_hcd *hcd) if (ehci->amd_pll_fix == 1) usb_amd_dev_put(); -#ifdef EHCI_STATS - ehci_dbg(ehci, "irq normal %ld err %ld iaa %ld (lost %ld)\n", - ehci->stats.normal, ehci->stats.error, ehci->stats.iaa, - ehci->stats.lost_iaa); - ehci_dbg (ehci, "complete %ld unlink %ld\n", - ehci->stats.complete, ehci->stats.unlink); -#endif - dbg_status (ehci, "ehci_stop completed", ehci_readl(ehci, &ehci->regs->status)); } @@ -487,6 +479,7 @@ static int ehci_init(struct usb_hcd *hcd) ehci->periodic_size = DEFAULT_I_TDPS; INIT_LIST_HEAD(&ehci->async_unlink); INIT_LIST_HEAD(&ehci->async_idle); + INIT_LIST_HEAD(&ehci->intr_unlink_wait); INIT_LIST_HEAD(&ehci->intr_unlink); INIT_LIST_HEAD(&ehci->intr_qh_list); INIT_LIST_HEAD(&ehci->cached_itd_list); @@ -942,7 +935,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); unsigned long flags; - struct ehci_qh *qh, *tmp; + struct ehci_qh *qh; /* ASSERT: any requests/urbs are being unlinked */ /* ASSERT: nobody can be submitting urbs for this any more */ @@ -972,17 +965,13 @@ rescan: qh->qh_state = QH_STATE_IDLE; switch (qh->qh_state) { case QH_STATE_LINKED: - case QH_STATE_COMPLETING: - for (tmp = ehci->async->qh_next.qh; - tmp && tmp != qh; - tmp = tmp->qh_next.qh) - continue; - /* periodic qh self-unlinks on empty, and a COMPLETING qh - * may already be unlinked. - */ - if (tmp) + WARN_ON(!list_empty(&qh->qtd_list)); + if (usb_endpoint_type(&ep->desc) != USB_ENDPOINT_XFER_INT) start_unlink_async(ehci, qh); + else + start_unlink_intr(ehci, qh); /* FALL THROUGH */ + case QH_STATE_COMPLETING: /* already in unlinking */ case QH_STATE_UNLINK: /* wait for hw to finish? */ case QH_STATE_UNLINK_WAIT: idle_timeout: @@ -1169,7 +1158,7 @@ static const struct hc_driver ehci_hc_driver = { * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, + .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, /* * basic lifecycle operations @@ -1303,7 +1292,7 @@ static int __init ehci_hcd_init(void) sizeof(struct ehci_qh), sizeof(struct ehci_qtd), sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); -#ifdef DEBUG +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root); if (!ehci_debug_root) { retval = -ENOENT; @@ -1352,7 +1341,7 @@ clean2: platform_driver_unregister(&PLATFORM_DRIVER); clean0: #endif -#ifdef DEBUG +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) debugfs_remove(ehci_debug_root); ehci_debug_root = NULL; err_debug: @@ -1376,7 +1365,7 @@ static void __exit ehci_hcd_cleanup(void) #ifdef PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); #endif -#ifdef DEBUG +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) debugfs_remove(ehci_debug_root); #endif clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 6dce37555c4..835fc0844a6 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -183,7 +183,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, spin_lock_irq(&ehci->lock); /* clear phy low-power mode before changing wakeup flags */ - if (ehci->has_hostpc) { + if (ehci->has_tdi_phy_lpm) { port = HCS_N_PORTS(ehci->hcs_params); while (port--) { u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; @@ -211,13 +211,11 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, else t2 |= PORT_WKOC_E | PORT_WKCONN_E; } - ehci_vdbg(ehci, "port %d, %08x -> %08x\n", - port + 1, t1, t2); ehci_writel(ehci, t2, reg); } /* enter phy low-power mode again */ - if (ehci->has_hostpc) { + if (ehci->has_tdi_phy_lpm) { port = HCS_N_PORTS(ehci->hcs_params); while (port--) { u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; @@ -302,14 +300,12 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) } if (t1 != t2) { - ehci_vdbg (ehci, "port %d, %08x -> %08x\n", - port + 1, t1, t2); ehci_writel(ehci, t2, reg); changed = 1; } } - if (changed && ehci->has_hostpc) { + if (changed && ehci->has_tdi_phy_lpm) { spin_unlock_irq(&ehci->lock); msleep(5); /* 5 ms for HCD to enter low-power mode */ spin_lock_irq(&ehci->lock); @@ -345,6 +341,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) end_unlink_async(ehci); unlink_empty_async_suspended(ehci); + ehci_handle_start_intr_unlinks(ehci); ehci_handle_intr_unlinks(ehci); end_free_itds(ehci); |