diff options
Diffstat (limited to 'drivers/usb/host')
41 files changed, 212 insertions, 1058 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a3ca1375dd52..fafc628480e0 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -292,11 +292,15 @@ config USB_EHCI_HCD_PLATFORM If unsure, say N. config USB_OCTEON_EHCI - bool "Octeon on-chip EHCI support" + bool "Octeon on-chip EHCI support (DEPRECATED)" depends on CAVIUM_OCTEON_SOC default n select USB_EHCI_BIG_ENDIAN_MMIO + select USB_EHCI_HCD_PLATFORM help + This option is deprecated now and the driver was removed, use + USB_EHCI_HCD_PLATFORM instead. + Enable support for the Octeon II SOC's on-chip EHCI controller. It is needed for high-speed (480Mbit/sec) USB 2.0 device support. All CN6XXX based chips with USB are @@ -575,12 +579,16 @@ config USB_OHCI_HCD_PLATFORM If unsure, say N. config USB_OCTEON_OHCI - bool "Octeon on-chip OHCI support" + bool "Octeon on-chip OHCI support (DEPRECATED)" depends on CAVIUM_OCTEON_SOC default USB_OCTEON_EHCI select USB_OHCI_BIG_ENDIAN_MMIO select USB_OHCI_LITTLE_ENDIAN + select USB_OHCI_HCD_PLATFORM help + This option is deprecated now and the driver was removed, use + USB_OHCI_HCD_PLATFORM instead. + Enable support for the Octeon II SOC's on-chip OHCI controller. It is needed for low-speed USB 1.0 device support. All CN6XXX based chips with USB are supported. @@ -754,12 +762,6 @@ config USB_IMX21_HCD To compile this driver as a module, choose M here: the module will be called "imx21-hcd". - - -config USB_OCTEON2_COMMON - bool - default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI - config USB_HCD_BCMA tristate "BCMA usb host driver" depends on BCMA diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 348c24321562..d6216a493bab 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -73,7 +73,6 @@ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o -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 diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index ec9f7b75d497..56a88506febe 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -107,22 +107,15 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - retval = -ENODEV; - goto fail_request_resource; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto fail_request_resource; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + iclk = devm_clk_get(&pdev->dev, "ehci_clk"); if (IS_ERR(iclk)) { dev_err(&pdev->dev, "Error getting interface clock\n"); diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 7189f2e32ac2..f58c9750e3e4 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -74,7 +74,6 @@ static int exynos_ehci_get_phy(struct device *dev, phy = devm_of_phy_get(dev, child, NULL); exynos_ehci->phy[phy_number] = phy; - of_node_put(child); if (IS_ERR(phy)) { ret = PTR_ERR(phy); if (ret == -EPROBE_DEFER) { @@ -188,20 +187,15 @@ skip_phy: goto fail_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto fail_io; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto fail_io; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "Failed to get IRQ\n"); diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 2d2ae8db439e..fb7bd0c7dc15 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -93,21 +93,15 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - retval = -ENODEV; - goto err2; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err2; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + pdata->regs = hcd->regs; if (pdata->power_budget) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 15feaf924b71..38bfeedae1d0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -311,6 +311,7 @@ static void unlink_empty_async_suspended(struct ehci_hcd *ehci); static void ehci_work(struct ehci_hcd *ehci); static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); +static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable); #include "ehci-timer.c" #include "ehci-hub.c" @@ -329,9 +330,13 @@ static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) { int port = HCS_N_PORTS(ehci->hcs_params); - while (port--) + while (port--) { ehci_writel(ehci, PORT_RWC_BITS, &ehci->regs->port_status[port]); + spin_unlock_irq(&ehci->lock); + ehci_port_power(ehci, port, false); + spin_lock_irq(&ehci->lock); + } } /* @@ -1233,6 +1238,8 @@ void ehci_init_driver(struct hc_driver *drv, drv->hcd_priv_size += over->extra_priv_size; if (over->reset) drv->reset = over->reset; + if (over->port_power) + drv->port_power = over->port_power; } } EXPORT_SYMBOL_GPL(ehci_init_driver); @@ -1268,11 +1275,6 @@ MODULE_LICENSE ("GPL"); #define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver #endif -#ifdef CONFIG_USB_OCTEON_EHCI -#include "ehci-octeon.c" -#define PLATFORM_DRIVER ehci_octeon_driver -#endif - #ifdef CONFIG_TILE_USB #include "ehci-tilegx.c" #define PLATFORM_DRIVER ehci_hcd_tilegx_driver diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 5728829cf6ef..118edb7bdca2 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -69,10 +69,8 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) if (test_bit(port, &ehci->owned_ports)) { reg = &ehci->regs->port_status[port]; status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; - if (!(status & PORT_POWER)) { - status |= PORT_POWER; - ehci_writel(ehci, status, reg); - } + if (!(status & PORT_POWER)) + ehci_port_power(ehci, port, true); } } @@ -952,9 +950,11 @@ int ehci_hub_control( clear_bit(wIndex, &ehci->port_c_suspend); break; case USB_PORT_FEAT_POWER: - if (HCS_PPC (ehci->hcs_params)) - ehci_writel(ehci, temp & ~PORT_POWER, - status_reg); + if (HCS_PPC(ehci->hcs_params)) { + spin_unlock_irqrestore(&ehci->lock, flags); + ehci_port_power(ehci, wIndex, false); + spin_lock_irqsave(&ehci->lock, flags); + } break; case USB_PORT_FEAT_C_CONNECTION: ehci_writel(ehci, temp | PORT_CSC, status_reg); @@ -1004,9 +1004,9 @@ int ehci_hub_control( */ if (((temp & PORT_OC) || (ehci->need_oc_pp_cycle)) && HCS_PPC(ehci->hcs_params)) { - ehci_writel(ehci, - temp & ~(PORT_RWC_BITS | PORT_POWER), - status_reg); + spin_unlock_irqrestore(&ehci->lock, flags); + ehci_port_power(ehci, wIndex, false); + spin_lock_irqsave(&ehci->lock, flags); temp = ehci_readl(ehci, status_reg); } } @@ -1187,9 +1187,11 @@ int ehci_hub_control( set_bit(wIndex, &ehci->suspended_ports); break; case USB_PORT_FEAT_POWER: - if (HCS_PPC (ehci->hcs_params)) - ehci_writel(ehci, temp | PORT_POWER, - status_reg); + if (HCS_PPC(ehci->hcs_params)) { + spin_unlock_irqrestore(&ehci->lock, flags); + ehci_port_power(ehci, wIndex, true); + spin_lock_irqsave(&ehci->lock, flags); + } break; case USB_PORT_FEAT_RESET: if (temp & (PORT_SUSPEND|PORT_RESUME)) @@ -1297,3 +1299,20 @@ static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) reg = &ehci->regs->port_status[portnum - 1]; return ehci_readl(ehci, reg) & PORT_OWNER; } + +static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable) +{ + struct usb_hcd *hcd = ehci_to_hcd(ehci); + u32 __iomem *status_reg = &ehci->regs->port_status[portnum]; + u32 temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS; + + if (enable) + ehci_writel(ehci, temp | PORT_POWER, status_reg); + else + ehci_writel(ehci, temp & ~PORT_POWER, status_reg); + + if (hcd->driver->port_power) + hcd->driver->port_power(hcd, portnum, enable); + + return 0; +} diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 9dc2118ae808..9db74ca7e5b9 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -88,19 +88,13 @@ static int ehci_msm_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get memory resource\n"); - ret = -ENODEV; - goto put_hcd; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto put_hcd; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); /* * OTG driver takes care of PHY initialization, clock management, diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 08147c35f836..849806a75f1c 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -153,7 +153,6 @@ static int mv_ehci_probe(struct platform_device *pdev) ehci_mv = devm_kzalloc(&pdev->dev, sizeof(*ehci_mv), GFP_KERNEL); if (ehci_mv == NULL) { - dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); retval = -ENOMEM; goto err_put_hcd; } @@ -170,12 +169,6 @@ static int mv_ehci_probe(struct platform_device *pdev) } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs"); - if (r == NULL) { - dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); - retval = -ENODEV; - goto err_put_hcd; - } - ehci_mv->phy_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->phy_regs)) { retval = PTR_ERR(ehci_mv->phy_regs); @@ -183,12 +176,6 @@ static int mv_ehci_probe(struct platform_device *pdev) } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs"); - if (!r) { - dev_err(&pdev->dev, "no I/O memory resource defined\n"); - retval = -ENODEV; - goto err_put_hcd; - } - ehci_mv->cap_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->cap_regs)) { retval = PTR_ERR(ehci_mv->cap_regs); diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index dbe5e4eea08d..c7a9b31eeaef 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -69,20 +69,13 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "Found HC with no register addr. Check setup!\n"); - ret = -ENODEV; - goto err_alloc; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err_alloc; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); hcd->has_tt = 1; ehci = hcd_to_ehci(hcd); diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c deleted file mode 100644 index 9051439039a7..000000000000 --- a/drivers/usb/host/ehci-octeon.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * EHCI HCD glue for Cavium Octeon II SOCs. - * - * Loosely based on ehci-au1xxx.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010 Cavium Networks - * - */ - -#include <linux/platform_device.h> - -#include <asm/octeon/octeon.h> -#include <asm/octeon/cvmx-uctlx-defs.h> - -#define OCTEON_EHCI_HCD_NAME "octeon-ehci" - -/* Common clock init code. */ -void octeon2_usb_clocks_start(void); -void octeon2_usb_clocks_stop(void); - -static void ehci_octeon_start(void) -{ - union cvmx_uctlx_ehci_ctl ehci_ctl; - - octeon2_usb_clocks_start(); - - ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); - /* Use 64-bit addressing. */ - ehci_ctl.s.ehci_64b_addr_en = 1; - ehci_ctl.s.l2c_addr_msb = 0; - ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ - ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ - cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64); -} - -static void ehci_octeon_stop(void) -{ - octeon2_usb_clocks_stop(); -} - -static const struct hc_driver ehci_octeon_hc_driver = { - .description = hcd_name, - .product_desc = "Octeon EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, - - /* - * basic lifecycle operations - */ - .reset = ehci_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static u64 ehci_octeon_dma_mask = DMA_BIT_MASK(64); - -static int ehci_octeon_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct ehci_hcd *ehci; - struct resource *res_mem; - int irq; - int ret; - - if (usb_disabled()) - return -ENODEV; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "No irq assigned\n"); - return -ENODEV; - } - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res_mem == NULL) { - dev_err(&pdev->dev, "No register space assigned\n"); - return -ENODEV; - } - - /* - * We can DMA from anywhere. But the descriptors must be in - * the lower 4GB. - */ - pdev->dev.dma_mask = &ehci_octeon_dma_mask; - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon"); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - - hcd->regs = devm_ioremap_resource(&pdev->dev, res_mem); - if (IS_ERR(hcd->regs)) { - ret = PTR_ERR(hcd->regs); - goto err1; - } - - ehci_octeon_start(); - - ehci = hcd_to_ehci(hcd); - - /* Octeon EHCI matches CPU endianness. */ -#ifdef __BIG_ENDIAN - ehci->big_endian_mmio = 1; -#endif - - ehci->caps = hcd->regs; - - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret) { - dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); - goto err2; - } - device_wakeup_enable(hcd->self.controller); - - platform_set_drvdata(pdev, hcd); - - return 0; -err2: - ehci_octeon_stop(); - -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ehci_octeon_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - - ehci_octeon_stop(); - usb_put_hcd(hcd); - - return 0; -} - -static struct platform_driver ehci_octeon_driver = { - .probe = ehci_octeon_drv_probe, - .remove = ehci_octeon_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = OCTEON_EHCI_HCD_NAME, - .owner = THIS_MODULE, - } -}; - -MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME); diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 22e15cab8ea5..3c76489ea61a 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -25,8 +25,8 @@ #include "ehci.h" -#define rdl(off) __raw_readl(hcd->regs + (off)) -#define wrl(off, val) __raw_writel((val), hcd->regs + (off)) +#define rdl(off) readl_relaxed(hcd->regs + (off)) +#define wrl(off, val) writel_relaxed((val), hcd->regs + (off)) #define USB_CMD 0x140 #define USB_MODE 0x1a8 @@ -175,15 +175,6 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) goto err; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - err = -ENODEV; - goto err; - } - /* * Right now device-tree probed devices don't get dma_mask * set. Since shared usb code relies on it, set it here for @@ -193,6 +184,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) if (err) goto err; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(regs)) { err = PTR_ERR(regs); diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 2f5b9ce3e042..35a9aeda0168 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -164,11 +164,6 @@ static int ehci_platform_probe(struct platform_device *dev) dev_err(&dev->dev, "no irq provided"); return irq; } - res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!res_mem) { - dev_err(&dev->dev, "no memory resource provided"); - return -ENXIO; - } hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, dev_name(&dev->dev)); @@ -250,14 +245,15 @@ static int ehci_platform_probe(struct platform_device *dev) goto err_reset; } - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - + res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto err_power; } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) goto err_power; @@ -311,8 +307,7 @@ static int ehci_platform_remove(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static int ehci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -348,11 +343,7 @@ static int ehci_platform_resume(struct device *dev) ehci_resume(hcd, false); return 0; } - -#else /* !CONFIG_PM */ -#define ehci_platform_suspend NULL -#define ehci_platform_resume NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static const struct of_device_id vt8500_ehci_ids[] = { { .compatible = "via,vt8500-ehci", }, @@ -368,10 +359,8 @@ static const struct platform_device_id ehci_platform_table[] = { }; MODULE_DEVICE_TABLE(platform, ehci_platform_table); -static const struct dev_pm_ops ehci_platform_pm_ops = { - .suspend = ehci_platform_suspend, - .resume = ehci_platform_resume, -}; +static SIMPLE_DEV_PM_OPS(ehci_platform_pm_ops, ehci_platform_suspend, + ehci_platform_resume); static struct platform_driver ehci_platform_driver = { .id_table = ehci_platform_table, diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index cf1267673868..9b6e8d0eac43 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c @@ -110,14 +110,13 @@ static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err1; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); /* Root hub has integrated TT. */ hcd->has_tt = 1; diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 9b9b9f5b016e..0e0ce684aff3 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -86,15 +86,6 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - ret = -ENODEV; - goto fail_create_hcd; - } - irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(&pdev->dev, @@ -114,19 +105,18 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) goto fail_create_hcd; } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto fail_request_resource; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); priv = devm_kzalloc(&pdev->dev, sizeof(struct ehci_sh_priv), GFP_KERNEL); if (!priv) { - dev_dbg(&pdev->dev, "error allocating priv data\n"); ret = -ENOMEM; goto fail_request_resource; } diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 1355ff0946b9..34e14746b92e 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -99,18 +99,13 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - retval = -ENODEV; - goto err_put_hcd; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err_put_hcd; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); sehci = to_spear_ehci(hcd); sehci->clk = usbh_clk; diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index aaa01971efe9..19a9af1b4d74 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -460,18 +460,14 @@ static int tegra_ehci_probe(struct platform_device *pdev) "nvidia,needs-double-reset"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto cleanup_clk_en; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto cleanup_clk_en; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + ehci->caps = hcd->regs + 0x100; ehci->has_hostpc = soc_config->has_hostpc; @@ -484,7 +480,6 @@ static int tegra_ehci_probe(struct platform_device *pdev) u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); if (!u_phy->otg) { - dev_err(&pdev->dev, "Failed to alloc memory for otg\n"); err = -ENOMEM; goto cleanup_phy; } diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index a9303aff125e..c305732e8634 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -42,27 +42,20 @@ static int usb_w90x900_probe(const struct hc_driver *driver, int retval = 0, irq; unsigned long val; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - retval = -ENXIO; - goto err1; - } - hcd = usb_create_hcd(driver, &pdev->dev, "w90x900 EHCI"); if (!hcd) { retval = -ENOMEM; goto err1; } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err2; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; @@ -82,8 +75,10 @@ static int usb_w90x900_probe(const struct hc_driver *driver, __raw_writel(val, ehci->regs+PHY1_CTR); irq = platform_get_irq(pdev, 0); - if (irq < 0) + if (irq < 0) { + retval = irq; goto err2; + } retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval != 0) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index eee228a26a0e..6f0577b0a5ae 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -859,6 +859,8 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) struct ehci_driver_overrides { size_t extra_priv_size; int (*reset)(struct usb_hcd *hcd); + int (*port_power)(struct usb_hcd *hcd, + int portnum, bool enable); }; extern void ehci_init_driver(struct hc_driver *drv, diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index ac6cd1bfd208..3bad17859cd7 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -1,6 +1,8 @@ #ifndef __LINUX_FOTG210_H #define __LINUX_FOTG210_H +#include <linux/usb/ehci-dbgp.h> + /* definitions used for the EHCI driver */ /* @@ -84,7 +86,7 @@ struct fotg210_hcd { /* one per controller */ /* glue to PCI and HCD framework */ struct fotg210_caps __iomem *caps; struct fotg210_regs __iomem *regs; - struct fotg210_dbg_port __iomem *debug; + struct ehci_dbg_port __iomem *debug; __u32 hcs_params; /* cached register copy */ spinlock_t lock; @@ -293,64 +295,6 @@ struct fotg210_regs { #define GMIR_MDEV_INT (1 << 0) }; -/* Appendix C, Debug port ... intended for use with special "debug devices" - * that can help if there's no serial console. (nonstandard enumeration.) - */ -struct fotg210_dbg_port { - u32 control; -#define DBGP_OWNER (1<<30) -#define DBGP_ENABLED (1<<28) -#define DBGP_DONE (1<<16) -#define DBGP_INUSE (1<<10) -#define DBGP_ERRCODE(x) (((x)>>7)&0x07) -# define DBGP_ERR_BAD 1 -# define DBGP_ERR_SIGNAL 2 -#define DBGP_ERROR (1<<6) -#define DBGP_GO (1<<5) -#define DBGP_OUT (1<<4) -#define DBGP_LEN(x) (((x)>>0)&0x0f) - u32 pids; -#define DBGP_PID_GET(x) (((x)>>16)&0xff) -#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok)) - u32 data03; - u32 data47; - u32 address; -#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) -}; - -#ifdef CONFIG_EARLY_PRINTK_DBGP -#include <linux/init.h> -extern int __init early_dbgp_init(char *s); -extern struct console early_dbgp_console; -#endif /* CONFIG_EARLY_PRINTK_DBGP */ - -struct usb_hcd; - -static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) -{ - return 1; /* Shouldn't this be 0? */ -} - -static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) -{ - return -1; -} - -#ifdef CONFIG_EARLY_PRINTK_DBGP -/* Call backs from fotg210 host driver to fotg210 debug driver */ -extern int dbgp_external_startup(struct usb_hcd *); -extern int dbgp_reset_prep(struct usb_hcd *hcd); -#else -static inline int dbgp_reset_prep(struct usb_hcd *hcd) -{ - return xen_dbgp_reset_prep(hcd); -} -static inline int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd); -} -#endif - /*-------------------------------------------------------------------------*/ #define QTD_NEXT(fotg210, dma) cpu_to_hc32(fotg210, (u32)dma) diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h index 6b719e066c3f..d6e5b3d4aa68 100644 --- a/drivers/usb/host/fusbh200.h +++ b/drivers/usb/host/fusbh200.h @@ -1,6 +1,8 @@ #ifndef __LINUX_FUSBH200_H #define __LINUX_FUSBH200_H +#include <linux/usb/ehci-dbgp.h> + /* definitions used for the EHCI driver */ /* @@ -84,7 +86,7 @@ struct fusbh200_hcd { /* one per controller */ /* glue to PCI and HCD framework */ struct fusbh200_caps __iomem *caps; struct fusbh200_regs __iomem *regs; - struct fusbh200_dbg_port __iomem *debug; + struct ehci_dbg_port __iomem *debug; __u32 hcs_params; /* cached register copy */ spinlock_t lock; @@ -285,64 +287,6 @@ struct fusbh200_regs { #define BMIER_VBUS_ERR_EN (1<<0) }; -/* Appendix C, Debug port ... intended for use with special "debug devices" - * that can help if there's no serial console. (nonstandard enumeration.) - */ -struct fusbh200_dbg_port { - u32 control; -#define DBGP_OWNER (1<<30) -#define DBGP_ENABLED (1<<28) -#define DBGP_DONE (1<<16) -#define DBGP_INUSE (1<<10) -#define DBGP_ERRCODE(x) (((x)>>7)&0x07) -# define DBGP_ERR_BAD 1 -# define DBGP_ERR_SIGNAL 2 -#define DBGP_ERROR (1<<6) -#define DBGP_GO (1<<5) -#define DBGP_OUT (1<<4) -#define DBGP_LEN(x) (((x)>>0)&0x0f) - u32 pids; -#define DBGP_PID_GET(x) (((x)>>16)&0xff) -#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok)) - u32 data03; - u32 data47; - u32 address; -#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) -}; - -#ifdef CONFIG_EARLY_PRINTK_DBGP -#include <linux/init.h> -extern int __init early_dbgp_init(char *s); -extern struct console early_dbgp_console; -#endif /* CONFIG_EARLY_PRINTK_DBGP */ - -struct usb_hcd; - -static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) -{ - return 1; /* Shouldn't this be 0? */ -} - -static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) -{ - return -1; -} - -#ifdef CONFIG_EARLY_PRINTK_DBGP -/* Call backs from fusbh200 host driver to fusbh200 debug driver */ -extern int dbgp_external_startup(struct usb_hcd *); -extern int dbgp_reset_prep(struct usb_hcd *hcd); -#else -static inline int dbgp_reset_prep(struct usb_hcd *hcd) -{ - return xen_dbgp_reset_prep(hcd); -} -static inline int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd); -} -#endif - /*-------------------------------------------------------------------------*/ #define QTD_NEXT(fusbh200, dma) cpu_to_hc32(fusbh200, (u32)dma) diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 207bad99301f..eb4efba9f1ad 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1174,11 +1174,11 @@ static int imx21_hc_urb_enqueue(struct usb_hcd *hcd, dev_vdbg(imx21->dev, "enqueue urb=%p ep=%p len=%d " - "buffer=%p dma=%08X setupBuf=%p setupDma=%08X\n", + "buffer=%p dma=%pad setupBuf=%p setupDma=%pad\n", urb, ep, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma, - urb->setup_packet, urb->setup_dma); + urb->transfer_buffer, &urb->transfer_dma, + urb->setup_packet, &urb->setup_dma); if (usb_pipeisoc(urb->pipe)) return imx21_hc_urb_enqueue_isoc(hcd, ep, urb, mem_flags); diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c deleted file mode 100644 index d9df423f3d12..000000000000 --- a/drivers/usb/host/octeon2-common.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010, 2011 Cavium Networks - */ - -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/delay.h> - -#include <asm/octeon/octeon.h> -#include <asm/octeon/cvmx-uctlx-defs.h> - -static DEFINE_MUTEX(octeon2_usb_clocks_mutex); - -static int octeon2_usb_clock_start_cnt; - -void octeon2_usb_clocks_start(void) -{ - u64 div; - union cvmx_uctlx_if_ena if_ena; - union cvmx_uctlx_clk_rst_ctl clk_rst_ctl; - union cvmx_uctlx_uphy_ctl_status uphy_ctl_status; - union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; - int i; - unsigned long io_clk_64_to_ns; - - - mutex_lock(&octeon2_usb_clocks_mutex); - - octeon2_usb_clock_start_cnt++; - if (octeon2_usb_clock_start_cnt != 1) - goto exit; - - io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); - - /* - * Step 1: Wait for voltages stable. That surely happened - * before starting the kernel. - * - * Step 2: Enable SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1 - */ - if_ena.u64 = 0; - if_ena.s.en = 1; - cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64); - - /* Step 3: Configure the reference clock, PHY, and HCLK */ - clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); - - /* - * If the UCTL looks like it has already been started, skip - * the initialization, otherwise bus errors are obtained. - */ - if (clk_rst_ctl.s.hrst) - goto end_clock; - /* 3a */ - clk_rst_ctl.s.p_por = 1; - clk_rst_ctl.s.hrst = 0; - clk_rst_ctl.s.p_prst = 0; - clk_rst_ctl.s.h_clkdiv_rst = 0; - clk_rst_ctl.s.o_clkdiv_rst = 0; - clk_rst_ctl.s.h_clkdiv_en = 0; - clk_rst_ctl.s.o_clkdiv_en = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3b */ - /* 12MHz crystal. */ - clk_rst_ctl.s.p_refclk_sel = 0; - clk_rst_ctl.s.p_refclk_div = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3c */ - div = octeon_get_io_clock_rate() / 130000000ull; - - switch (div) { - case 0: - div = 1; - break; - case 1: - case 2: - case 3: - case 4: - break; - case 5: - div = 4; - break; - case 6: - case 7: - div = 6; - break; - case 8: - case 9: - case 10: - case 11: - div = 8; - break; - default: - div = 12; - break; - } - clk_rst_ctl.s.h_div = div; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - /* Read it back, */ - clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); - clk_rst_ctl.s.h_clkdiv_en = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - /* 3d */ - clk_rst_ctl.s.h_clkdiv_rst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3e: delay 64 io clocks */ - ndelay(io_clk_64_to_ns); - - /* - * Step 4: Program the power-on reset field in the UCTL - * clock-reset-control register. - */ - clk_rst_ctl.s.p_por = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* Step 5: Wait 1 ms for the PHY clock to start. */ - mdelay(1); - - /* - * Step 6: Program the reset input from automatic test - * equipment field in the UPHY CSR - */ - uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0)); - uphy_ctl_status.s.ate_reset = 1; - cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); - - /* Step 7: Wait for at least 10ns. */ - ndelay(10); - - /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */ - uphy_ctl_status.s.ate_reset = 0; - cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); - - /* - * Step 9: Wait for at least 20ns for UPHY to output PHY clock - * signals and OHCI_CLK48 - */ - ndelay(20); - - /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */ - /* 10a */ - clk_rst_ctl.s.o_clkdiv_rst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 10b */ - clk_rst_ctl.s.o_clkdiv_en = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 10c */ - ndelay(io_clk_64_to_ns); - - /* - * Step 11: Program the PHY reset field: - * UCTL0_CLK_RST_CTL[P_PRST] = 1 - */ - clk_rst_ctl.s.p_prst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* Step 12: Wait 1 uS. */ - udelay(1); - - /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */ - clk_rst_ctl.s.hrst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - -end_clock: - /* Now we can set some other registers. */ - - for (i = 0; i <= 1; i++) { - port_ctl_status.u64 = - cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0)); - /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */ - port_ctl_status.s.txvreftune = 15; - port_ctl_status.s.txrisetune = 1; - port_ctl_status.s.txpreemphasistune = 1; - cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), - port_ctl_status.u64); - } - - /* Set uSOF cycle period to 60,000 bits. */ - cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull); -exit: - mutex_unlock(&octeon2_usb_clocks_mutex); -} -EXPORT_SYMBOL(octeon2_usb_clocks_start); - -void octeon2_usb_clocks_stop(void) -{ - mutex_lock(&octeon2_usb_clocks_mutex); - octeon2_usb_clock_start_cnt--; - mutex_unlock(&octeon2_usb_clocks_mutex); -} -EXPORT_SYMBOL(octeon2_usb_clocks_stop); diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index e49eb4f90f5d..39406607e53a 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -24,12 +24,8 @@ #include <linux/usb.h> #include <linux/usb/hcd.h> -#include <mach/hardware.h> #include <asm/gpio.h> -#include <mach/cpu.h> - - #include "ohci.h" #define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS) @@ -137,12 +133,6 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, struct resource *res; int irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_dbg(dev, "hcd probe: missing memory resource\n"); - return -ENXIO; - } - irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_dbg(dev, "hcd probe: missing irq resource\n"); @@ -152,14 +142,15 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, hcd = usb_create_hcd(driver, dev, "at91"); if (!hcd) return -ENOMEM; - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); iclk = devm_clk_get(dev, "ohci_clk"); if (IS_ERR(iclk)) { diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index df06be6b47f5..1c76999b2184 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -313,16 +313,13 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver, return -ENOMEM; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -ENODEV; - hcd->rsrc_start = mem->start; - hcd->rsrc_len = resource_size(mem); - hcd->regs = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(hcd->regs)) { error = PTR_ERR(hcd->regs); goto err; } + hcd->rsrc_start = mem->start; + hcd->rsrc_len = resource_size(mem); ohci_hcd_init(hcd_to_ohci(hcd)); diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index d28b6583ba02..035a8a85a867 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -63,7 +63,6 @@ static int exynos_ohci_get_phy(struct device *dev, phy = devm_of_phy_get(dev, child, NULL); exynos_ohci->phy[phy_number] = phy; - of_node_put(child); if (IS_ERR(phy)) { ret = PTR_ERR(phy); if (ret == -EPROBE_DEFER) { @@ -156,19 +155,13 @@ skip_phy: goto fail_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto fail_io; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto fail_io; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); irq = platform_get_irq(pdev, 0); if (!irq) { diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d664edabf14e..1dab9dfbca6a 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1249,11 +1249,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_jz4740_driver #endif -#ifdef CONFIG_USB_OCTEON_OHCI -#include "ohci-octeon.c" -#define PLATFORM_DRIVER ohci_octeon_driver -#endif - #ifdef CONFIG_TILE_USB #include "ohci-tilegx.c" #define PLATFORM_DRIVER ohci_hcd_tilegx_driver diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index c2c221a332eb..8ddd8f5470cb 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -153,13 +153,6 @@ static int jz4740_ohci_probe(struct platform_device *pdev) struct resource *res; int irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!res) { - dev_err(&pdev->dev, "Failed to get platform resource\n"); - return -ENOENT; - } - irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "Failed to get platform irq\n"); @@ -174,14 +167,14 @@ static int jz4740_ohci_probe(struct platform_device *pdev) jz4740_ohci = hcd_to_jz4740_hcd(hcd); - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err_free; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); jz4740_ohci->clk = devm_clk_get(&pdev->dev, "uhc"); if (IS_ERR(jz4740_ohci->clk)) { diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c deleted file mode 100644 index 15af8954085e..000000000000 --- a/drivers/usb/host/ohci-octeon.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * EHCI HCD glue for Cavium Octeon II SOCs. - * - * Loosely based on ehci-au1xxx.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010 Cavium Networks - * - */ - -#include <linux/platform_device.h> - -#include <asm/octeon/octeon.h> -#include <asm/octeon/cvmx-uctlx-defs.h> - -#define OCTEON_OHCI_HCD_NAME "octeon-ohci" - -/* Common clock init code. */ -void octeon2_usb_clocks_start(void); -void octeon2_usb_clocks_stop(void); - -static void ohci_octeon_hw_start(void) -{ - union cvmx_uctlx_ohci_ctl ohci_ctl; - - octeon2_usb_clocks_start(); - - ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); - ohci_ctl.s.l2c_addr_msb = 0; - ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ - ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ - cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64); - -} - -static void ohci_octeon_hw_stop(void) -{ - /* Undo ohci_octeon_start() */ - octeon2_usb_clocks_stop(); -} - -static int ohci_octeon_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - ret = ohci_init(ohci); - - if (ret < 0) - return ret; - - ret = ohci_run(ohci); - - if (ret < 0) { - ohci_err(ohci, "can't start %s", hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static const struct hc_driver ohci_octeon_hc_driver = { - .description = hcd_name, - .product_desc = "Octeon OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_octeon_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, - - .start_port_reset = ohci_start_port_reset, -}; - -static int ohci_octeon_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct ohci_hcd *ohci; - void *reg_base; - struct resource *res_mem; - int irq; - int ret; - - if (usb_disabled()) - return -ENODEV; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "No irq assigned\n"); - return -ENODEV; - } - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res_mem == NULL) { - dev_err(&pdev->dev, "No register space assigned\n"); - return -ENODEV; - } - - /* Ohci is a 32-bit device. */ - ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - hcd = usb_create_hcd(&ohci_octeon_hc_driver, &pdev->dev, "octeon"); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - - reg_base = devm_ioremap_resource(&pdev->dev, res_mem); - if (IS_ERR(reg_base)) { - ret = PTR_ERR(reg_base); - goto err1; - } - - ohci_octeon_hw_start(); - - hcd->regs = reg_base; - - ohci = hcd_to_ohci(hcd); - - /* Octeon OHCI matches CPU endianness. */ -#ifdef __BIG_ENDIAN - ohci->flags |= OHCI_QUIRK_BE_MMIO; -#endif - - ohci_hcd_init(ohci); - - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret) { - dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); - goto err2; - } - - device_wakeup_enable(hcd->self.controller); - - platform_set_drvdata(pdev, hcd); - - return 0; - -err2: - ohci_octeon_hw_stop(); - -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ohci_octeon_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - - ohci_octeon_hw_stop(); - usb_put_hcd(hcd); - - return 0; -} - -static struct platform_driver ohci_octeon_driver = { - .probe = ohci_octeon_drv_probe, - .remove = ohci_octeon_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = OCTEON_OHCI_HCD_NAME, - .owner = THIS_MODULE, - } -}; - -MODULE_ALIAS("platform:" OCTEON_OHCI_HCD_NAME); diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 0231606d47c2..3e5df5af3740 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -183,7 +183,7 @@ static void start_hnp(struct ohci_hcd *ohci) otg_start_hnp(hcd->usb_phy->otg); local_irq_save(flags); - hcd->usb_phy->state = OTG_STATE_A_SUSPEND; + hcd->usb_phy->otg->state = OTG_STATE_A_SUSPEND; writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); l = omap_readl(OTG_CTRL); l &= ~OTG_A_BUSREQ; diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 4369299064c7..9434c1d54495 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -43,20 +43,6 @@ struct ohci_platform_priv { static const char hcd_name[] = "ohci-platform"; -static int ohci_platform_reset(struct usb_hcd *hcd) -{ - struct platform_device *pdev = to_platform_device(hcd->self.controller); - struct usb_ohci_pdata *pdata = dev_get_platdata(&pdev->dev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - if (pdata->no_big_frame_no) - ohci->flags |= OHCI_QUIRK_FRAME_NO; - if (pdata->num_ports) - ohci->num_ports = pdata->num_ports; - - return ohci_setup(hcd); -} - static int ohci_platform_power_on(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); @@ -110,7 +96,6 @@ static struct hc_driver __read_mostly ohci_platform_hc_driver; static const struct ohci_driver_overrides platform_overrides __initconst = { .product_desc = "Generic Platform OHCI controller", - .reset = ohci_platform_reset, .extra_priv_size = sizeof(struct ohci_platform_priv), }; @@ -149,12 +134,6 @@ static int ohci_platform_probe(struct platform_device *dev) return irq; } - res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!res_mem) { - dev_err(&dev->dev, "no memory resource provided"); - return -ENXIO; - } - hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, dev_name(&dev->dev)); if (!hcd) @@ -175,6 +154,12 @@ static int ohci_platform_probe(struct platform_device *dev) if (of_property_read_bool(dev->dev.of_node, "big-endian")) ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; + if (of_property_read_bool(dev->dev.of_node, "no-big-frame-no")) + ohci->flags |= OHCI_QUIRK_FRAME_NO; + + of_property_read_u32(dev->dev.of_node, "num-ports", + &ohci->num_ports); + priv->phy = devm_phy_get(&dev->dev, "usb"); if (IS_ERR(priv->phy)) { err = PTR_ERR(priv->phy); @@ -212,6 +197,10 @@ static int ohci_platform_probe(struct platform_device *dev) ohci->flags |= OHCI_QUIRK_BE_DESC; if (pdata->big_endian_mmio) ohci->flags |= OHCI_QUIRK_BE_MMIO; + if (pdata->no_big_frame_no) + ohci->flags |= OHCI_QUIRK_FRAME_NO; + if (pdata->num_ports) + ohci->num_ports = pdata->num_ports; #ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO if (ohci->flags & OHCI_QUIRK_BE_MMIO) { @@ -236,14 +225,15 @@ static int ohci_platform_probe(struct platform_device *dev) goto err_reset; } - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - + res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto err_power; } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) goto err_power; @@ -298,8 +288,7 @@ static int ohci_platform_remove(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static int ohci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -335,11 +324,7 @@ static int ohci_platform_resume(struct device *dev) ohci_resume(hcd, false); return 0; } - -#else /* !CONFIG_PM */ -#define ohci_platform_suspend NULL -#define ohci_platform_resume NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static const struct of_device_id ohci_platform_ids[] = { { .compatible = "generic-ohci", }, @@ -353,10 +338,8 @@ static const struct platform_device_id ohci_platform_table[] = { }; MODULE_DEVICE_TABLE(platform, ohci_platform_table); -static const struct dev_pm_ops ohci_platform_pm_ops = { - .suspend = ohci_platform_suspend, - .resume = ohci_platform_resume, -}; +static SIMPLE_DEV_PM_OPS(ohci_platform_pm_ops, ohci_platform_suspend, + ohci_platform_resume); static struct platform_driver ohci_platform_driver = { .id_table = ohci_platform_table, diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e68f3d02cd1a..13399814ef5f 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -447,20 +447,13 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) { - pr_err("no resource of IORESOURCE_MEM"); - retval = -ENXIO; - goto err; - } - - hcd->rsrc_start = r->start; - hcd->rsrc_len = resource_size(r); - hcd->regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err; } + hcd->rsrc_start = r->start; + hcd->rsrc_len = resource_size(r); /* initialize "struct pxa27x_ohci" */ pxa_ohci = to_pxa27x_ohci(hcd); diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 8d5876692e7c..4a54f9d73136 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -74,20 +74,15 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - retval = -ENODEV; - goto err_put_hcd; - } - - hcd->rsrc_start = pdev->resource[0].start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err_put_hcd; } + hcd->rsrc_start = pdev->resource[0].start; + hcd->rsrc_len = resource_size(res); + sohci_p = to_spear_ohci(hcd); sohci_p->clk = usbh_clk; diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 59f424567a8d..bc462288cfb0 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -647,23 +647,22 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) /*-------------------------------------------------------------------------*/ -/* HCCA frame number is 16 bits, but is accessed as 32 bits since not all - * hardware handles 16 bit reads. That creates a different confusion on - * some big-endian SOC implementations. Same thing happens with PSW access. +/* + * The HCCA frame number is 16 bits, but is accessed as 32 bits since not all + * hardware handles 16 bit reads. Depending on the SoC implementation, the + * frame number can wind up in either bits [31:16] (default) or + * [15:0] (OHCI_QUIRK_FRAME_NO) on big endian hosts. + * + * Somewhat similarly, the 16-bit PSW fields in a transfer descriptor are + * reordered on BE. */ -#ifdef CONFIG_PPC_MPC52xx -#define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO) -#else -#define big_endian_frame_no_quirk(ohci) 0 -#endif - static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) { u32 tmp; if (big_endian_desc(ohci)) { tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); - if (!big_endian_frame_no_quirk(ohci)) + if (!(ohci->flags & OHCI_QUIRK_FRAME_NO)) tmp >>= 16; } else tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 4fe79a2d71a9..75811dd5a9d7 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -3846,7 +3846,6 @@ static int oxu_drv_probe(struct platform_device *pdev) */ info = devm_kzalloc(&pdev->dev, sizeof(struct oxu_info), GFP_KERNEL); if (!info) { - dev_dbg(&pdev->dev, "error allocating memory\n"); ret = -EFAULT; goto error; } diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 2f3acebb577a..dd483c13565b 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -233,10 +233,8 @@ commit: spin_unlock_irqrestore(&amd_lock, flags); - if (info.nb_dev) - pci_dev_put(info.nb_dev); - if (info.smbus_dev) - pci_dev_put(info.smbus_dev); + pci_dev_put(info.nb_dev); + pci_dev_put(info.smbus_dev); } else { /* no race - commit the result */ @@ -447,10 +445,8 @@ void usb_amd_dev_put(void) spin_unlock_irqrestore(&amd_lock, flags); - if (nb) - pci_dev_put(nb); - if (smbus) - pci_dev_put(smbus); + pci_dev_put(nb); + pci_dev_put(smbus); } EXPORT_SYMBOL_GPL(usb_amd_dev_put); diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index b987f1d10058..cf8f46003f62 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -86,14 +86,14 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err_rmr; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + uhci = hcd_to_uhci(hcd); uhci->regs = hcd->regs; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 646300cbe5f7..08d402b15482 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -83,9 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; if (of_device_is_compatible(pdev->dev.of_node, "marvell,armada-375-xhci") || @@ -109,15 +106,16 @@ static int xhci_plat_probe(struct platform_device *pdev) if (!hcd) return -ENOMEM; - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto put_hcd; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + /* * Not all platforms have a clk so it is not an error if the * clock does not exists. diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 06433aec81d7..e692e769c50c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -716,9 +716,7 @@ remove_finished_td: ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } - /* Clear stopped_td if endpoint is not halted */ - if (!(ep->ep_state & EP_HALTED)) - ep->stopped_td = NULL; + ep->stopped_td = NULL; /* * Drop the lock and complete the URBs in the cancelled TD list. @@ -1732,13 +1730,11 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, return; ep->ep_state |= EP_HALTED; - ep->stopped_td = td; ep->stopped_stream = stream_id; xhci_queue_reset_ep(xhci, command, slot_id, ep_index); - xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index); + xhci_cleanup_stalled_ring(xhci, ep_index, td); - ep->stopped_td = NULL; ep->stopped_stream = 0; xhci_ring_cmd_db(xhci); @@ -1813,72 +1809,65 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, if (skip) goto td_cleanup; - if (trb_comp_code == COMP_STOP_INVAL || - trb_comp_code == COMP_STOP) { + if (trb_comp_code == COMP_STOP_INVAL || trb_comp_code == COMP_STOP) { /* The Endpoint Stop Command completion will take care of any * stopped TDs. A stopped TD may be restarted, so don't update * the ring dequeue pointer or take this TD off any lists yet. */ ep->stopped_td = td; return 0; + } + if (trb_comp_code == COMP_STALL || + xhci_requires_manual_halt_cleanup(xhci, ep_ctx, + trb_comp_code)) { + /* Issue a reset endpoint command to clear the host side + * halt, followed by a set dequeue command to move the + * dequeue pointer past the TD. + * The class driver clears the device side halt later. + */ + xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index, + ep_ring->stream_id, td, event_trb); } else { - if (trb_comp_code == COMP_STALL || - xhci_requires_manual_halt_cleanup(xhci, ep_ctx, - trb_comp_code)) { - /* Issue a reset endpoint command to clear the host side - * halt, followed by a set dequeue command to move the - * dequeue pointer past the TD. - * The class driver clears the device side halt later. - */ - xhci_cleanup_halted_endpoint(xhci, - slot_id, ep_index, ep_ring->stream_id, - td, event_trb); - } else { - /* Update ring dequeue pointer */ - while (ep_ring->dequeue != td->last_trb) - inc_deq(xhci, ep_ring); + /* Update ring dequeue pointer */ + while (ep_ring->dequeue != td->last_trb) inc_deq(xhci, ep_ring); - } + inc_deq(xhci, ep_ring); + } td_cleanup: - /* Clean up the endpoint's TD list */ - urb = td->urb; - urb_priv = urb->hcpriv; - - /* Do one last check of the actual transfer length. - * If the host controller said we transferred more data than - * the buffer length, urb->actual_length will be a very big - * number (since it's unsigned). Play it safe and say we didn't - * transfer anything. - */ - if (urb->actual_length > urb->transfer_buffer_length) { - xhci_warn(xhci, "URB transfer length is wrong, " - "xHC issue? req. len = %u, " - "act. len = %u\n", - urb->transfer_buffer_length, - urb->actual_length); - urb->actual_length = 0; - if (td->urb->transfer_flags & URB_SHORT_NOT_OK) - *status = -EREMOTEIO; - else - *status = 0; - } - list_del_init(&td->td_list); - /* Was this TD slated to be cancelled but completed anyway? */ - if (!list_empty(&td->cancelled_td_list)) - list_del_init(&td->cancelled_td_list); - - urb_priv->td_cnt++; - /* Giveback the urb when all the tds are completed */ - if (urb_priv->td_cnt == urb_priv->length) { - ret = 1; - if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { - xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; - if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs - == 0) { - if (xhci->quirks & XHCI_AMD_PLL_FIX) - usb_amd_quirk_pll_enable(); - } + /* Clean up the endpoint's TD list */ + urb = td->urb; + urb_priv = urb->hcpriv; + + /* Do one last check of the actual transfer length. + * If the host controller said we transferred more data than the buffer + * length, urb->actual_length will be a very big number (since it's + * unsigned). Play it safe and say we didn't transfer anything. + */ + if (urb->actual_length > urb->transfer_buffer_length) { + xhci_warn(xhci, "URB transfer length is wrong, xHC issue? req. len = %u, act. len = %u\n", + urb->transfer_buffer_length, + urb->actual_length); + urb->actual_length = 0; + if (td->urb->transfer_flags & URB_SHORT_NOT_OK) + *status = -EREMOTEIO; + else + *status = 0; + } + list_del_init(&td->td_list); + /* Was this TD slated to be cancelled but completed anyway? */ + if (!list_empty(&td->cancelled_td_list)) + list_del_init(&td->cancelled_td_list); + + urb_priv->td_cnt++; + /* Giveback the urb when all the tds are completed */ + if (urb_priv->td_cnt == urb_priv->length) { + ret = 1; + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { + xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; + if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { + if (xhci->quirks & XHCI_AMD_PLL_FIX) + usb_amd_quirk_pll_enable(); } } } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index cf3413116aff..01fcbb5eb06e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2912,10 +2912,11 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, } void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, - struct usb_device *udev, unsigned int ep_index) + unsigned int ep_index, struct xhci_td *td) { struct xhci_dequeue_state deq_state; struct xhci_virt_ep *ep; + struct usb_device *udev = td->urb->dev; xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, "Cleaning up stalled endpoint ring"); @@ -2924,8 +2925,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, * or it will attempt to resend it on the next doorbell ring. */ xhci_find_new_dequeue_state(xhci, udev->slot_id, - ep_index, ep->stopped_stream, ep->stopped_td, - &deq_state); + ep_index, ep->stopped_stream, td, &deq_state); if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg) return; @@ -4009,6 +4009,7 @@ static int __maybe_unused xhci_change_max_exit_latency(struct xhci_hcd *xhci, slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT)); slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency); + slot_ctx->dev_state = 0; xhci_dbg_trace(xhci, trace_xhci_dbg_context_change, "Set up evaluate context for LPM MEL change."); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d745715a1e2f..cc7c5bb7cbcf 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -358,7 +358,7 @@ struct xhci_op_regs { /* wake on over-current (enable) */ #define PORT_WKOC_E (1 << 27) /* bits 28:29 reserved */ -/* true: device is removable - for USB 3.0 roothub emulation */ +/* true: device is non-removable - for USB 3.0 roothub emulation */ #define PORT_DEV_REMOVE (1 << 30) /* Initiate a warm port reset - complete when PORT_WRC is '1' */ #define PORT_WR (1 << 31) @@ -1825,7 +1825,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, unsigned int stream_id, struct xhci_dequeue_state *deq_state); void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, - struct usb_device *udev, unsigned int ep_index); + unsigned int ep_index, struct xhci_td *td); void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state); |