diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/Kconfig | 7 | ||||
-rw-r--r-- | drivers/usb/host/ehci-exynos.c | 11 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 52 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.h | 3 | ||||
-rw-r--r-- | drivers/usb/host/ehci-st.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/fotg210-hcd.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/fsl-mph-dr-of.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/isp1362.h | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci-exynos.c | 11 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci-s3c2410.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci-spear.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/ohci-st.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/u132-hcd.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 27 | ||||
-rw-r--r-- | drivers/usb/host/xhci-tegra.c | 23 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 23 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 5 |
18 files changed, 138 insertions, 60 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d809671c5fea..40b5de597112 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -114,7 +114,7 @@ config USB_EHCI_HCD Controller Driver or UHCI (for Via motherboards) Host Controller Driver too. - You may want to read <file:Documentation/usb/ehci.txt>. + You may want to read <file:Documentation/usb/ehci.rst>. To compile this driver as a module, choose M here: the module will be called ehci-hcd. @@ -161,7 +161,6 @@ config USB_EHCI_PCI config USB_EHCI_HCD_PMC_MSP tristate "EHCI support for on-chip PMC MSP71xx USB controller" depends on MSP_HAS_USB - default n select USB_EHCI_BIG_ENDIAN_DESC select USB_EHCI_BIG_ENDIAN_MMIO ---help--- @@ -308,7 +307,6 @@ config USB_CNS3XXX_EHCI config USB_EHCI_HCD_PLATFORM tristate "Generic EHCI driver for a platform device" - default n ---help--- Adds an EHCI host driver for a generic platform device, which provides a memory space and an irq. @@ -318,7 +316,6 @@ config USB_EHCI_HCD_PLATFORM config USB_OCTEON_EHCI bool "Octeon on-chip EHCI support (DEPRECATED)" depends on CAVIUM_OCTEON_SOC - default n select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN select USB_EHCI_HCD_PLATFORM help @@ -526,7 +523,6 @@ config USB_OHCI_HCD_SSB depends on (SSB = y || SSB = USB_OHCI_HCD) select USB_HCD_SSB select USB_OHCI_HCD_PLATFORM - default n ---help--- This option is deprecated now and the driver was removed, use USB_HCD_SSB and USB_OHCI_HCD_PLATFORM instead. @@ -569,7 +565,6 @@ config USB_CNS3XXX_OHCI config USB_OHCI_HCD_PLATFORM tristate "Generic OHCI driver for a platform device" - default n ---help--- Adds an OHCI host driver for a generic platform device, which provides a memory space and an irq. diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 8e3bab1e0c1f..3a29a1a8519c 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -39,6 +39,7 @@ static struct hc_driver __read_mostly exynos_ehci_hc_driver; struct exynos_ehci_hcd { struct clk *clk; + struct device_node *of_node; struct phy *phy[PHY_NUMBER]; }; @@ -203,6 +204,13 @@ static int exynos_ehci_probe(struct platform_device *pdev) ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; + /* + * Workaround: reset of_node pointer to avoid conflict between Exynos + * EHCI port subnodes and generic USB device bindings + */ + exynos_ehci->of_node = pdev->dev.of_node; + pdev->dev.of_node = NULL; + /* DMA burst Enable */ writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); @@ -219,6 +227,7 @@ static int exynos_ehci_probe(struct platform_device *pdev) fail_add_hcd: exynos_ehci_phy_disable(&pdev->dev); + pdev->dev.of_node = exynos_ehci->of_node; fail_io: clk_disable_unprepare(exynos_ehci->clk); fail_clk: @@ -231,6 +240,8 @@ static int exynos_ehci_remove(struct platform_device *pdev) struct usb_hcd *hcd = platform_get_drvdata(pdev); struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); + pdev->dev.of_node = exynos_ehci->of_node; + usb_remove_hcd(hcd); exynos_ehci_phy_disable(&pdev->dev); diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index e3d0c1c25160..9e9c232e896f 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -122,6 +122,12 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) tmp |= 0x4; iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); } + + /* Set USB_EN bit to select ULPI phy for USB controller version 2.5 */ + if (pdata->controller_ver == FSL_USB_VER_2_5 && + pdata->phy_mode == FSL_USB2_PHY_ULPI) + iowrite32be(USB_CTRL_USB_EN, hcd->regs + FSL_SOC_USB_CTRL); + /* * Enable UTMI phy and program PTS field in UTMI mode before asserting * controller reset for USB Controller version 2.5 @@ -177,6 +183,17 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) return retval; } +static bool usb_phy_clk_valid(struct usb_hcd *hcd) +{ + void __iomem *non_ehci = hcd->regs; + bool ret = true; + + if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) + ret = false; + + return ret; +} + static int ehci_fsl_setup_phy(struct usb_hcd *hcd, enum fsl_usb2_phy_modes phy_mode, unsigned int port_offset) @@ -219,7 +236,26 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, portsc |= PORT_PTS_PTW; /* fall through */ case FSL_USB2_PHY_UTMI: + /* Presence of this node "has_fsl_erratum_a006918" + * in device-tree is used to stop USB controller + * initialization in Linux + */ + if (pdata->has_fsl_erratum_a006918) { + dev_warn(dev, "USB PHY clock invalid\n"); + return -EINVAL; + } + /* fall through */ case FSL_USB2_PHY_UTMI_DUAL: + /* PHY_CLK_VALID bit is de-featured from all controller + * versions below 2.4 and is to be checked only for + * internal UTMI phy + */ + if (pdata->controller_ver > FSL_USB_VER_2_4 && + pdata->have_sysif_regs && !usb_phy_clk_valid(hcd)) { + dev_err(dev, "USB PHY clock invalid\n"); + return -EINVAL; + } + if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); @@ -243,17 +279,11 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, break; } - /* - * check PHY_CLK_VALID to determine phy clock presence before writing - * to portsc - */ - if (pdata->check_phy_clk_valid) { - if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & - PHY_CLK_VALID)) { - dev_warn(hcd->self.controller, - "USB PHY clock invalid\n"); - return -EINVAL; - } + if (pdata->have_sysif_regs && + pdata->controller_ver > FSL_USB_VER_1_6 && + !usb_phy_clk_valid(hcd)) { + dev_warn(hcd->self.controller, "USB PHY clock invalid\n"); + return -EINVAL; } ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index cbc422032e50..9d18c6e6ab27 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -50,4 +50,7 @@ #define UTMI_PHY_EN (1<<9) #define ULPI_PHY_CLK_SEL (1<<10) #define PHY_CLK_VALID (1<<17) + +/* Retry count for checking UTMI PHY CLK validity */ +#define UTMI_PHY_CLK_VALID_CHK_RETRY 5 #endif /* _EHCI_FSL_H */ diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c index dc42981047c9..ccb4e611001d 100644 --- a/drivers/usb/host/ehci-st.c +++ b/drivers/usb/host/ehci-st.c @@ -152,7 +152,6 @@ static int st_ehci_platform_probe(struct platform_device *dev) struct resource *res_mem; struct usb_ehci_pdata *pdata = &ehci_platform_defaults; struct st_ehci_platform_priv *priv; - struct ehci_hcd *ehci; int err, irq, clk = 0; if (usb_disabled()) @@ -177,7 +176,6 @@ static int st_ehci_platform_probe(struct platform_device *dev) platform_set_drvdata(dev, hcd); dev->dev.platform_data = pdata; priv = hcd_to_ehci_priv(hcd); - ehci = hcd_to_ehci(hcd); priv->phy = devm_phy_get(&dev->dev, "usb"); if (IS_ERR(priv->phy)) { diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 0da68df259c8..e835a22b12af 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -10,6 +10,7 @@ * Most of code borrowed from the Linux-3.7 EHCI driver */ #include <linux/module.h> +#include <linux/of.h> #include <linux/device.h> #include <linux/dmapool.h> #include <linux/kernel.h> @@ -5669,9 +5670,18 @@ static int fotg210_hcd_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id fotg210_of_match[] = { + { .compatible = "faraday,fotg210" }, + {}, +}; +MODULE_DEVICE_TABLE(of, fotg210_of_match); +#endif + static struct platform_driver fotg210_hcd_driver = { .driver = { .name = "fotg210-hcd", + .of_match_table = of_match_ptr(fotg210_of_match), }, .probe = fotg210_hcd_probe, .remove = fotg210_hcd_remove, diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 4f8b8a08c914..ae8f60f6e6a5 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -224,12 +224,10 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) of_property_read_bool(np, "fsl,usb-erratum-a005275"); pdata->has_fsl_erratum_a005697 = of_property_read_bool(np, "fsl,usb_erratum-a005697"); - - if (of_get_property(np, "fsl,usb_erratum_14", NULL)) - pdata->has_fsl_erratum_14 = 1; - else - pdata->has_fsl_erratum_14 = 0; - + pdata->has_fsl_erratum_a006918 = + of_property_read_bool(np, "fsl,usb_erratum-a006918"); + pdata->has_fsl_erratum_14 = + of_property_read_bool(np, "fsl,usb_erratum-14"); /* * Determine whether phy_clk_valid needs to be checked diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h index 650240846ee2..4c49688a069d 100644 --- a/drivers/usb/host/isp1362.h +++ b/drivers/usb/host/isp1362.h @@ -11,7 +11,7 @@ #define USE_32BIT 0 -/* These options are mutually eclusive */ +/* These options are mutually exclusive */ #define USE_PLATFORM_DELAY 0 #define USE_NDELAY 0 diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index c0c4dcca6f3c..905c6317e0c3 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -30,6 +30,7 @@ static struct hc_driver __read_mostly exynos_ohci_hc_driver; struct exynos_ohci_hcd { struct clk *clk; + struct device_node *of_node; struct phy *phy[PHY_NUMBER]; }; @@ -170,6 +171,13 @@ static int exynos_ohci_probe(struct platform_device *pdev) goto fail_io; } + /* + * Workaround: reset of_node pointer to avoid conflict between Exynos + * OHCI port subnodes and generic USB device bindings + */ + exynos_ohci->of_node = pdev->dev.of_node; + pdev->dev.of_node = NULL; + err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD\n"); @@ -180,6 +188,7 @@ static int exynos_ohci_probe(struct platform_device *pdev) fail_add_hcd: exynos_ohci_phy_disable(&pdev->dev); + pdev->dev.of_node = exynos_ohci->of_node; fail_io: clk_disable_unprepare(exynos_ohci->clk); fail_clk: @@ -192,6 +201,8 @@ static int exynos_ohci_remove(struct platform_device *pdev) struct usb_hcd *hcd = platform_get_drvdata(pdev); struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); + pdev->dev.of_node = exynos_ohci->of_node; + usb_remove_hcd(hcd); exynos_ohci_phy_disable(&pdev->dev); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index fbcd34911025..a033f7d855e0 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -274,7 +274,7 @@ static const struct ohci_driver_overrides pci_overrides __initconst = { .reset = ohci_pci_reset, }; -static const struct pci_device_id pci_ids [] = { { +static const struct pci_device_id pci_ids[] = { { /* handle any USB OHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), .driver_data = (unsigned long) &ohci_pci_hc_driver, diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 4511e27e9da8..d961097c90f0 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -293,7 +293,6 @@ static int ohci_s3c2410_hub_control( static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) { struct s3c2410_hcd_port *port; - struct usb_hcd *hcd; unsigned long flags; int portno; @@ -301,7 +300,6 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) return; port = &info->port[0]; - hcd = info->hcd; local_irq_save(flags); diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 69fa04697793..5cc05449281c 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -35,7 +35,6 @@ static struct hc_driver __read_mostly ohci_spear_hc_driver; static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) { const struct hc_driver *driver = &ohci_spear_hc_driver; - struct ohci_hcd *ohci; struct usb_hcd *hcd = NULL; struct clk *usbh_clk; struct spear_ohci *sohci_p; @@ -85,8 +84,6 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) clk_prepare_enable(sohci_p->clk); - ohci = hcd_to_ohci(hcd); - retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0); if (retval == 0) { device_wakeup_enable(hcd->self.controller); diff --git a/drivers/usb/host/ohci-st.c b/drivers/usb/host/ohci-st.c index 992807c9850a..638a92bd2cdc 100644 --- a/drivers/usb/host/ohci-st.c +++ b/drivers/usb/host/ohci-st.c @@ -132,7 +132,6 @@ static int st_ohci_platform_probe(struct platform_device *dev) struct resource *res_mem; struct usb_ohci_pdata *pdata = &ohci_platform_defaults; struct st_ohci_platform_priv *priv; - struct ohci_hcd *ohci; int err, irq, clk = 0; if (usb_disabled()) @@ -158,7 +157,6 @@ static int st_ohci_platform_probe(struct platform_device *dev) platform_set_drvdata(dev, hcd); dev->dev.platform_data = pdata; priv = hcd_to_ohci_priv(hcd); - ohci = hcd_to_ohci(hcd); priv->phy = devm_phy_get(&dev->dev, "usb"); if (IS_ERR(priv->phy)) { diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 4a5c9b599c57..400c40bc43a6 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2554,10 +2554,9 @@ static int u132_get_frame(struct usb_hcd *hcd) dev_err(&u132->platform_dev->dev, "device is being removed\n"); return -ESHUTDOWN; } else { - int frame = 0; dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n"); mdelay(100); - return frame; + return 0; } } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 121782e22c01..9741cdeea9d7 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -399,7 +399,7 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, * stream once the endpoint is on the HW schedule. */ if ((ep_state & EP_STOP_CMD_PENDING) || (ep_state & SET_DEQ_PENDING) || - (ep_state & EP_HALTED)) + (ep_state & EP_HALTED) || (ep_state & EP_CLEARING_TT)) return; writel(DB_VALUE(ep_index, stream_id), db_addr); /* The CPU has better things to do at this point than wait for a @@ -433,6 +433,13 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, } } +void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci, + unsigned int slot_id, + unsigned int ep_index) +{ + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); +} + /* Get the right ring for the given slot_id, ep_index and stream_id. * If the endpoint supports streams, boundary check the URB's stream ID. * If the endpoint doesn't support streams, return the singular endpoint ring. @@ -1799,6 +1806,23 @@ struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, return NULL; } +static void xhci_clear_hub_tt_buffer(struct xhci_hcd *xhci, struct xhci_td *td, + struct xhci_virt_ep *ep) +{ + /* + * As part of low/full-speed endpoint-halt processing + * we must clear the TT buffer (USB 2.0 specification 11.17.5). + */ + if (td->urb->dev->tt && !usb_pipeint(td->urb->pipe) && + (td->urb->dev->tt->hub != xhci_to_hcd(xhci)->self.root_hub) && + !(ep->ep_state & EP_CLEARING_TT)) { + ep->ep_state |= EP_CLEARING_TT; + td->urb->ep->hcpriv = td->urb->dev; + if (usb_hub_clear_tt_buffer(td->urb)) + ep->ep_state &= ~EP_CLEARING_TT; + } +} + static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id, struct xhci_td *td, @@ -1825,6 +1849,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, if (reset_type == EP_HARD_RESET) { ep->ep_state |= EP_HARD_CLEAR_TOGGLE; xhci_cleanup_stalled_ring(xhci, ep_index, stream_id, td); + xhci_clear_hub_tt_buffer(xhci, td, ep); } xhci_ring_cmd_db(xhci); } diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 294158113d62..dafc65911fc0 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -354,29 +354,6 @@ enum tegra_xusb_mbox_cmd { MBOX_CMD_NAK }; -static const char * const mbox_cmd_name[] = { - [ 1] = "MSG_ENABLE", - [ 2] = "INC_FALCON_CLOCK", - [ 3] = "DEC_FALCON_CLOCK", - [ 4] = "INC_SSPI_CLOCK", - [ 5] = "DEC_SSPI_CLOCK", - [ 6] = "SET_BW", - [ 7] = "SET_SS_PWR_GATING", - [ 8] = "SET_SS_PWR_UNGATING", - [ 9] = "SAVE_DFE_CTLE_CTX", - [ 10] = "AIRPLANE_MODE_ENABLED", - [ 11] = "AIRPLANE_MODE_DISABLED", - [ 12] = "START_HSIC_IDLE", - [ 13] = "STOP_HSIC_IDLE", - [ 14] = "DBC_WAKE_STACK", - [ 15] = "HSIC_PRETEND_CONNECT", - [ 16] = "RESET_SSPI", - [ 17] = "DISABLE_SS_LFPS_DETECTION", - [ 18] = "ENABLE_SS_LFPS_DETECTION", - [128] = "ACK", - [129] = "NAK", -}; - struct tegra_xusb_mbox_msg { u32 cmd; u32 data; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3f79f35d0b19..248cd7a8b163 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4130,6 +4130,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, /* Zero the input context control for later use */ ctrl_ctx->add_flags = 0; ctrl_ctx->drop_flags = 0; + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); + udev->devaddr = (u8)(le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Internal device address = %d", @@ -5176,6 +5178,26 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) } EXPORT_SYMBOL_GPL(xhci_gen_setup); +static void xhci_clear_tt_buffer_complete(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct xhci_hcd *xhci; + struct usb_device *udev; + unsigned int slot_id; + unsigned int ep_index; + unsigned long flags; + + xhci = hcd_to_xhci(hcd); + udev = (struct usb_device *)ep->hcpriv; + slot_id = udev->slot_id; + ep_index = xhci_get_endpoint_index(&ep->desc); + + spin_lock_irqsave(&xhci->lock, flags); + xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_CLEARING_TT; + xhci_ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); +} + static const struct hc_driver xhci_hc_driver = { .description = "xhci-hcd", .product_desc = "xHCI Host Controller", @@ -5237,6 +5259,7 @@ static const struct hc_driver xhci_hc_driver = { .enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout, .disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout, .find_raw_port_number = xhci_find_raw_port_number, + .clear_tt_buffer_complete = xhci_clear_tt_buffer_complete, }; void xhci_init_driver(struct hc_driver *drv, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 92e764c54154..7a264962a1a9 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -936,6 +936,8 @@ struct xhci_virt_ep { #define EP_GETTING_NO_STREAMS (1 << 5) #define EP_HARD_CLEAR_TOGGLE (1 << 6) #define EP_SOFT_CLEAR_TOGGLE (1 << 7) +/* usb_hub_clear_tt_buffer is in progress */ +#define EP_CLEARING_TT (1 << 8) /* ---- Related to URB cancellation ---- */ struct list_head cancelled_td_list; /* Watchdog timer for stop endpoint command to cancel URBs */ @@ -2111,6 +2113,9 @@ void xhci_handle_command_timeout(struct work_struct *work); void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); +void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci, + unsigned int slot_id, + unsigned int ep_index); void xhci_cleanup_command_queue(struct xhci_hcd *xhci); void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring); unsigned int count_trbs(u64 addr, u64 len); |