summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig37
-rw-r--r--drivers/usb/host/Makefile5
-rw-r--r--drivers/usb/host/alchemy-common.c614
-rw-r--r--drivers/usb/host/bcma-hcd.c15
-rw-r--r--drivers/usb/host/ehci-atmel.c15
-rw-r--r--drivers/usb/host/ehci-au1xxx.c184
-rw-r--r--drivers/usb/host/ehci-cns3xxx.c155
-rw-r--r--drivers/usb/host/ehci-dbg.c112
-rw-r--r--drivers/usb/host/ehci-fsl.c10
-rw-r--r--drivers/usb/host/ehci-grlib.c20
-rw-r--r--drivers/usb/host/ehci-hcd.c214
-rw-r--r--drivers/usb/host/ehci-hub.c47
-rw-r--r--drivers/usb/host/ehci-ixp4xx.c139
-rw-r--r--drivers/usb/host/ehci-lpm.c84
-rw-r--r--drivers/usb/host/ehci-ls1x.c147
-rw-r--r--drivers/usb/host/ehci-msm.c5
-rw-r--r--drivers/usb/host/ehci-mv.c4
-rw-r--r--drivers/usb/host/ehci-mxc.c129
-rw-r--r--drivers/usb/host/ehci-octeon.c3
-rw-r--r--drivers/usb/host/ehci-omap.c6
-rw-r--r--drivers/usb/host/ehci-orion.c58
-rw-r--r--drivers/usb/host/ehci-pci.c171
-rw-r--r--drivers/usb/host/ehci-platform.c102
-rw-r--r--drivers/usb/host/ehci-pmcmsp.c1
-rw-r--r--drivers/usb/host/ehci-ppc-of.c4
-rw-r--r--drivers/usb/host/ehci-ps3.c2
-rw-r--r--drivers/usb/host/ehci-q.c12
-rw-r--r--drivers/usb/host/ehci-s5p.c16
-rw-r--r--drivers/usb/host/ehci-sched.c136
-rw-r--r--drivers/usb/host/ehci-sh.c9
-rw-r--r--drivers/usb/host/ehci-spear.c59
-rw-r--r--drivers/usb/host/ehci-tegra.c18
-rw-r--r--drivers/usb/host/ehci-vt8500.c21
-rw-r--r--drivers/usb/host/ehci-w90x900.c10
-rw-r--r--drivers/usb/host/ehci-xilinx-of.c2
-rw-r--r--drivers/usb/host/ehci-xls.c142
-rw-r--r--drivers/usb/host/ehci.h52
-rw-r--r--drivers/usb/host/fhci-hcd.c8
-rw-r--r--drivers/usb/host/fsl-mph-dr-of.c19
-rw-r--r--drivers/usb/host/imx21-hcd.c3
-rw-r--r--drivers/usb/host/isp116x-hcd.c2
-rw-r--r--drivers/usb/host/isp1362-hcd.c6
-rw-r--r--drivers/usb/host/isp1760-if.c15
-rw-r--r--drivers/usb/host/ohci-at91.c24
-rw-r--r--drivers/usb/host/ohci-au1xxx.c234
-rw-r--r--drivers/usb/host/ohci-cns3xxx.c166
-rw-r--r--drivers/usb/host/ohci-ep93xx.c4
-rw-r--r--drivers/usb/host/ohci-exynos.c38
-rw-r--r--drivers/usb/host/ohci-hcd.c139
-rw-r--r--drivers/usb/host/ohci-hub.c42
-rw-r--r--drivers/usb/host/ohci-jz4740.c6
-rw-r--r--drivers/usb/host/ohci-nxp.c4
-rw-r--r--drivers/usb/host/ohci-octeon.c2
-rw-r--r--drivers/usb/host/ohci-omap.c7
-rw-r--r--drivers/usb/host/ohci-omap3.c7
-rw-r--r--drivers/usb/host/ohci-pci.c49
-rw-r--r--drivers/usb/host/ohci-platform.c34
-rw-r--r--drivers/usb/host/ohci-pnx8550.c243
-rw-r--r--drivers/usb/host/ohci-ppc-of.c4
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c216
-rw-r--r--drivers/usb/host/ohci-ps3.c4
-rw-r--r--drivers/usb/host/ohci-pxa27x.c8
-rw-r--r--drivers/usb/host/ohci-q.c23
-rw-r--r--drivers/usb/host/ohci-s3c2410.c41
-rw-r--r--drivers/usb/host/ohci-sa1111.c2
-rw-r--r--drivers/usb/host/ohci-sh.c141
-rw-r--r--drivers/usb/host/ohci-sm501.c2
-rw-r--r--drivers/usb/host/ohci-spear.c50
-rw-r--r--drivers/usb/host/ohci-tmio.c11
-rw-r--r--drivers/usb/host/ohci-xls.c152
-rw-r--r--drivers/usb/host/pci-quirks.c20
-rw-r--r--drivers/usb/host/r8a66597-hcd.c12
-rw-r--r--drivers/usb/host/sl811-hcd.c6
-rw-r--r--drivers/usb/host/ssb-hcd.c19
-rw-r--r--drivers/usb/host/u132-hcd.c6
-rw-r--r--drivers/usb/host/uhci-grlib.c2
-rw-r--r--drivers/usb/host/uhci-hcd.c15
-rw-r--r--drivers/usb/host/uhci-platform.c2
-rw-r--r--drivers/usb/host/uhci-q.c73
-rw-r--r--drivers/usb/host/xhci-hub.c38
-rw-r--r--drivers/usb/host/xhci-mem.c11
-rw-r--r--drivers/usb/host/xhci-pci.c16
-rw-r--r--drivers/usb/host/xhci-ring.c43
-rw-r--r--drivers/usb/host/xhci.c42
-rw-r--r--drivers/usb/host/xhci.h2
85 files changed, 973 insertions, 3800 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3f1431d37e1..3a21c5d683c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -95,6 +95,11 @@ config USB_EHCI_TT_NEWSCHED
If unsure, say Y.
+config USB_EHCI_PCI
+ tristate
+ depends on USB_EHCI_HCD && PCI
+ default y
+
config USB_EHCI_HCD_PMC_MSP
tristate "EHCI support for on-chip PMC MSP71xx USB controller"
depends on USB_EHCI_HCD && MSP_HAS_USB
@@ -143,7 +148,7 @@ config USB_EHCI_FSL
Variation of ARC USB block used in some Freescale chips.
config USB_EHCI_MXC
- bool "Support for Freescale i.MX on-chip EHCI USB controller"
+ tristate "Support for Freescale i.MX on-chip EHCI USB controller"
depends on USB_EHCI_HCD && ARCH_MXC
select USB_EHCI_ROOT_HUB_TT
---help---
@@ -215,9 +220,13 @@ config USB_W90X900_EHCI
Enables support for the W90X900 USB controller
config USB_CNS3XXX_EHCI
- bool "Cavium CNS3XXX EHCI Module"
+ bool "Cavium CNS3XXX EHCI Module (DEPRECATED)"
depends on USB_EHCI_HCD && ARCH_CNS3XXX
+ 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 CNS3XXX SOC's on-chip EHCI controller.
It is needed for high-speed (480Mbit/sec) USB 2.0 device
support.
@@ -333,16 +342,6 @@ config USB_OHCI_ATH79
Enables support for the built-in OHCI controller present on the
Atheros AR71XX/AR7240 SoCs.
-config USB_OHCI_HCD_PPC_SOC
- bool "OHCI support for on-chip PPC USB controller"
- depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
- default y
- select USB_OHCI_BIG_ENDIAN_DESC
- select USB_OHCI_BIG_ENDIAN_MMIO
- ---help---
- Enables support for the USB controller on the MPC52xx or
- STB03xxx processor chip. If unsure, say Y.
-
config USB_OHCI_HCD_PPC_OF_BE
bool "OHCI support for OF platform bus (big endian)"
depends on USB_OHCI_HCD && PPC_OF
@@ -393,9 +392,13 @@ config USB_OHCI_HCD_SSB
If unsure, say N.
config USB_OHCI_SH
- bool "OHCI support for SuperH USB controller"
+ bool "OHCI support for SuperH USB controller (DEPRECATED)"
depends on USB_OHCI_HCD && SUPERH
+ select USB_OHCI_HCD_PLATFORM
---help---
+ This option is deprecated now and the driver was removed, use
+ USB_OHCI_HCD_PLATFORM instead.
+
Enables support for the on-chip OHCI controller on the SuperH.
If you use the PCI OHCI controller, this option is not necessary.
@@ -406,9 +409,13 @@ config USB_OHCI_EXYNOS
Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
config USB_CNS3XXX_OHCI
- bool "Cavium CNS3XXX OHCI Module"
+ bool "Cavium CNS3XXX OHCI Module (DEPRECATED)"
depends on USB_OHCI_HCD && ARCH_CNS3XXX
+ 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 CNS3XXX SOC's on-chip OHCI controller.
It is needed for low-speed USB 1.0 device support.
@@ -423,7 +430,7 @@ config USB_OHCI_HCD_PLATFORM
If unsure, say N.
config USB_EHCI_HCD_PLATFORM
- bool "Generic EHCI driver for a platform device"
+ tristate "Generic EHCI driver for a platform device"
depends on USB_EHCI_HCD
default n
---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9e0a89ced15..001fbff2fde 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -24,6 +24,10 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci/
obj-$(CONFIG_PCI) += pci-quirks.o
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
+obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
+obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o
+obj-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
+
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o
@@ -40,6 +44,5 @@ 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_MIPS_ALCHEMY) += alchemy-common.o
obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o
diff --git a/drivers/usb/host/alchemy-common.c b/drivers/usb/host/alchemy-common.c
deleted file mode 100644
index 936af8359fb..00000000000
--- a/drivers/usb/host/alchemy-common.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * USB block power/access management abstraction.
- *
- * Au1000+: The OHCI block control register is at the far end of the OHCI memory
- * area. Au1550 has OHCI on different base address. No need to handle
- * UDC here.
- * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG
- * as well as the PHY for EHCI and UDC.
- *
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/syscore_ops.h>
-#include <asm/mach-au1x00/au1000.h>
-
-/* control register offsets */
-#define AU1000_OHCICFG 0x7fffc
-#define AU1550_OHCICFG 0x07ffc
-#define AU1200_USBCFG 0x04
-
-/* Au1000 USB block config bits */
-#define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */
-#define USBHEN_CE (1 << 3) /* OHCI block clock enable */
-#define USBHEN_E (1 << 2) /* OHCI block enable */
-#define USBHEN_C (1 << 1) /* OHCI block coherency bit */
-#define USBHEN_BE (1 << 0) /* OHCI Big-Endian */
-
-/* Au1200 USB config bits */
-#define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */
-#define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */
-#define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */
-#define USBCFG_SSD (1 << 23) /* serial short detect en */
-#define USBCFG_PPE (1 << 19) /* HS PHY PLL */
-#define USBCFG_UCE (1 << 18) /* UDC clock enable */
-#define USBCFG_ECE (1 << 17) /* EHCI clock enable */
-#define USBCFG_OCE (1 << 16) /* OHCI clock enable */
-#define USBCFG_FLA(x) (((x) & 0x3f) << 8)
-#define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */
-#define USBCFG_GME (1 << 6) /* OTG mem access */
-#define USBCFG_DBE (1 << 5) /* UDC busmaster enable */
-#define USBCFG_DME (1 << 4) /* UDC mem enable */
-#define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */
-#define USBCFG_EME (1 << 2) /* EHCI mem enable */
-#define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */
-#define USBCFG_OME (1 << 0) /* OHCI mem enable */
-#define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\
- USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \
- USBCFG_GME | USBCFG_DBE | USBCFG_DME | \
- USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \
- USBCFG_OME)
-
-/* Au1300 USB config registers */
-#define USB_DWC_CTRL1 0x00
-#define USB_DWC_CTRL2 0x04
-#define USB_VBUS_TIMER 0x10
-#define USB_SBUS_CTRL 0x14
-#define USB_MSR_ERR 0x18
-#define USB_DWC_CTRL3 0x1C
-#define USB_DWC_CTRL4 0x20
-#define USB_OTG_STATUS 0x28
-#define USB_DWC_CTRL5 0x2C
-#define USB_DWC_CTRL6 0x30
-#define USB_DWC_CTRL7 0x34
-#define USB_PHY_STATUS 0xC0
-#define USB_INT_STATUS 0xC4
-#define USB_INT_ENABLE 0xC8
-
-#define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */
-#define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */
-#define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */
-
-#define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */
-#define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */
-#define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */
-
-#define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19)
-#define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18)
-#define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17)
-#define USB_DWC_CTRL3_OTG0_CKEN (1 << 16)
-
-#define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */
-
-#define USB_INTEN_FORCE 0x20
-#define USB_INTEN_PHY 0x10
-#define USB_INTEN_UDC 0x08
-#define USB_INTEN_EHCI 0x04
-#define USB_INTEN_OHCI1 0x02
-#define USB_INTEN_OHCI0 0x01
-
-static DEFINE_SPINLOCK(alchemy_usb_lock);
-
-static inline void __au1300_usb_phyctl(void __iomem *base, int enable)
-{
- unsigned long r, s;
-
- r = __raw_readl(base + USB_DWC_CTRL2);
- s = __raw_readl(base + USB_DWC_CTRL3);
-
- s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN |
- USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN;
-
- if (enable) {
- /* simply enable all PHYs */
- r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
- USB_DWC_CTRL2_PHYRS;
- __raw_writel(r, base + USB_DWC_CTRL2);
- wmb();
- } else if (!s) {
- /* no USB block active, do disable all PHYs */
- r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
- USB_DWC_CTRL2_PHYRS);
- __raw_writel(r, base + USB_DWC_CTRL2);
- wmb();
- }
-}
-
-static inline void __au1300_ohci_control(void __iomem *base, int enable, int id)
-{
- unsigned long r;
-
- if (enable) {
- __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */
- r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
- : USB_DWC_CTRL3_OHCI1_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable); /* power up the PHYs */
-
- r = __raw_readl(base + USB_INT_ENABLE);
- r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- /* reset the OHCI start clock bit */
- __raw_writel(0, base + USB_DWC_CTRL7);
- wmb();
- } else {
- r = __raw_readl(base + USB_INT_ENABLE);
- r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1);
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3);
- r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
- : USB_DWC_CTRL3_OHCI1_CKEN);
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline void __au1300_ehci_control(void __iomem *base, int enable)
-{
- unsigned long r;
-
- if (enable) {
- r = __raw_readl(base + USB_DWC_CTRL3);
- r |= USB_DWC_CTRL3_EHCI0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r |= USB_DWC_CTRL1_HSTRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
-
- r = __raw_readl(base + USB_INT_ENABLE);
- r |= USB_INTEN_EHCI;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
- } else {
- r = __raw_readl(base + USB_INT_ENABLE);
- r &= ~USB_INTEN_EHCI;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r &= ~USB_DWC_CTRL1_HSTRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3);
- r &= ~USB_DWC_CTRL3_EHCI0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline void __au1300_udc_control(void __iomem *base, int enable)
-{
- unsigned long r;
-
- if (enable) {
- r = __raw_readl(base + USB_DWC_CTRL1);
- r |= USB_DWC_CTRL1_DCRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
-
- r = __raw_readl(base + USB_INT_ENABLE);
- r |= USB_INTEN_UDC;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
- } else {
- r = __raw_readl(base + USB_INT_ENABLE);
- r &= ~USB_INTEN_UDC;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r &= ~USB_DWC_CTRL1_DCRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline void __au1300_otg_control(void __iomem *base, int enable)
-{
- unsigned long r;
- if (enable) {
- r = __raw_readl(base + USB_DWC_CTRL3);
- r |= USB_DWC_CTRL3_OTG0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r &= ~USB_DWC_CTRL1_OTGD;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- } else {
- r = __raw_readl(base + USB_DWC_CTRL1);
- r |= USB_DWC_CTRL1_OTGD;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3);
- r &= ~USB_DWC_CTRL3_OTG0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline int au1300_usb_control(int block, int enable)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
- int ret = 0;
-
- switch (block) {
- case ALCHEMY_USB_OHCI0:
- __au1300_ohci_control(base, enable, 0);
- break;
- case ALCHEMY_USB_OHCI1:
- __au1300_ohci_control(base, enable, 1);
- break;
- case ALCHEMY_USB_EHCI0:
- __au1300_ehci_control(base, enable);
- break;
- case ALCHEMY_USB_UDC0:
- __au1300_udc_control(base, enable);
- break;
- case ALCHEMY_USB_OTG0:
- __au1300_otg_control(base, enable);
- break;
- default:
- ret = -ENODEV;
- }
- return ret;
-}
-
-static inline void au1300_usb_init(void)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
-
- /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4
- * here at all: Port 2 routing (EHCI or UDC) must be set either
- * by boot firmware or platform init code; I can't autodetect
- * a sane setting.
- */
- __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */
- wmb();
- __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */
- wmb();
- __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */
- wmb();
- __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */
- wmb();
- /* set coherent access bit */
- __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL);
- wmb();
-}
-
-static inline void __au1200_ohci_control(void __iomem *base, int enable)
-{
- unsigned long r = __raw_readl(base + AU1200_USBCFG);
- if (enable) {
- __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG);
- wmb();
- udelay(2000);
- } else {
- __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
- }
-}
-
-static inline void __au1200_ehci_control(void __iomem *base, int enable)
-{
- unsigned long r = __raw_readl(base + AU1200_USBCFG);
- if (enable) {
- __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
- } else {
- if (!(r & USBCFG_UCE)) /* UDC also off? */
- r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
- __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
- }
-}
-
-static inline void __au1200_udc_control(void __iomem *base, int enable)
-{
- unsigned long r = __raw_readl(base + AU1200_USBCFG);
- if (enable) {
- __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG);
- wmb();
- } else {
- if (!(r & USBCFG_ECE)) /* EHCI also off? */
- r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
- __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG);
- wmb();
- }
-}
-
-static inline int au1200_coherency_bug(void)
-{
-#if defined(CONFIG_DMA_COHERENT)
- /* Au1200 AB USB does not support coherent memory */
- if (!(read_c0_prid() & 0xff)) {
- printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n");
- printk(KERN_INFO "Au1200 USB: update your board or re-configure"
- " the kernel\n");
- return -ENODEV;
- }
-#endif
- return 0;
-}
-
-static inline int au1200_usb_control(int block, int enable)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
- int ret = 0;
-
- switch (block) {
- case ALCHEMY_USB_OHCI0:
- ret = au1200_coherency_bug();
- if (ret && enable)
- goto out;
- __au1200_ohci_control(base, enable);
- break;
- case ALCHEMY_USB_UDC0:
- __au1200_udc_control(base, enable);
- break;
- case ALCHEMY_USB_EHCI0:
- ret = au1200_coherency_bug();
- if (ret && enable)
- goto out;
- __au1200_ehci_control(base, enable);
- break;
- default:
- ret = -ENODEV;
- }
-out:
- return ret;
-}
-
-
-/* initialize USB block(s) to a known working state */
-static inline void au1200_usb_init(void)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
- __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
-}
-
-static inline void au1000_usb_init(unsigned long rb, int reg)
-{
- void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
- unsigned long r = __raw_readl(base);
-
-#if defined(__BIG_ENDIAN)
- r |= USBHEN_BE;
-#endif
- r |= USBHEN_C;
-
- __raw_writel(r, base);
- wmb();
- udelay(1000);
-}
-
-
-static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
-{
- void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
- unsigned long r = __raw_readl(base + creg);
-
- if (enable) {
- __raw_writel(r | USBHEN_CE, base + creg);
- wmb();
- udelay(1000);
- __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg);
- wmb();
- udelay(1000);
-
- /* wait for reset complete (read reg twice: au1500 erratum) */
- while (__raw_readl(base + creg),
- !(__raw_readl(base + creg) & USBHEN_RD))
- udelay(1000);
- } else {
- __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
- wmb();
- }
-}
-
-static inline int au1000_usb_control(int block, int enable, unsigned long rb,
- int creg)
-{
- int ret = 0;
-
- switch (block) {
- case ALCHEMY_USB_OHCI0:
- __au1xx0_ohci_control(enable, rb, creg);
- break;
- default:
- ret = -ENODEV;
- }
- return ret;
-}
-
-/*
- * alchemy_usb_control - control Alchemy on-chip USB blocks
- * @block: USB block to target
- * @enable: set 1 to enable a block, 0 to disable
- */
-int alchemy_usb_control(int block, int enable)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&alchemy_usb_lock, flags);
- switch (alchemy_get_cputype()) {
- case ALCHEMY_CPU_AU1000:
- case ALCHEMY_CPU_AU1500:
- case ALCHEMY_CPU_AU1100:
- ret = au1000_usb_control(block, enable,
- AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1550:
- ret = au1000_usb_control(block, enable,
- AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1200:
- ret = au1200_usb_control(block, enable);
- break;
- case ALCHEMY_CPU_AU1300:
- ret = au1300_usb_control(block, enable);
- break;
- default:
- ret = -ENODEV;
- }
- spin_unlock_irqrestore(&alchemy_usb_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL_GPL(alchemy_usb_control);
-
-
-static unsigned long alchemy_usb_pmdata[2];
-
-static void au1000_usb_pm(unsigned long br, int creg, int susp)
-{
- void __iomem *base = (void __iomem *)KSEG1ADDR(br);
-
- if (susp) {
- alchemy_usb_pmdata[0] = __raw_readl(base + creg);
- /* There appears to be some undocumented reset register.... */
- __raw_writel(0, base + 0x04);
- wmb();
- __raw_writel(0, base + creg);
- wmb();
- } else {
- __raw_writel(alchemy_usb_pmdata[0], base + creg);
- wmb();
- }
-}
-
-static void au1200_usb_pm(int susp)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR);
- if (susp) {
- /* save OTG_CAP/MUX registers which indicate port routing */
- /* FIXME: write an OTG driver to do that */
- alchemy_usb_pmdata[0] = __raw_readl(base + 0x00);
- alchemy_usb_pmdata[1] = __raw_readl(base + 0x04);
- } else {
- /* restore access to all MMIO areas */
- au1200_usb_init();
-
- /* restore OTG_CAP/MUX registers */
- __raw_writel(alchemy_usb_pmdata[0], base + 0x00);
- __raw_writel(alchemy_usb_pmdata[1], base + 0x04);
- wmb();
- }
-}
-
-static void au1300_usb_pm(int susp)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
- /* remember Port2 routing */
- if (susp) {
- alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4);
- } else {
- au1300_usb_init();
- __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4);
- wmb();
- }
-}
-
-static void alchemy_usb_pm(int susp)
-{
- switch (alchemy_get_cputype()) {
- case ALCHEMY_CPU_AU1000:
- case ALCHEMY_CPU_AU1500:
- case ALCHEMY_CPU_AU1100:
- au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp);
- break;
- case ALCHEMY_CPU_AU1550:
- au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp);
- break;
- case ALCHEMY_CPU_AU1200:
- au1200_usb_pm(susp);
- break;
- case ALCHEMY_CPU_AU1300:
- au1300_usb_pm(susp);
- break;
- }
-}
-
-static int alchemy_usb_suspend(void)
-{
- alchemy_usb_pm(1);
- return 0;
-}
-
-static void alchemy_usb_resume(void)
-{
- alchemy_usb_pm(0);
-}
-
-static struct syscore_ops alchemy_usb_pm_ops = {
- .suspend = alchemy_usb_suspend,
- .resume = alchemy_usb_resume,
-};
-
-static int __init alchemy_usb_init(void)
-{
- switch (alchemy_get_cputype()) {
- case ALCHEMY_CPU_AU1000:
- case ALCHEMY_CPU_AU1500:
- case ALCHEMY_CPU_AU1100:
- au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1550:
- au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1200:
- au1200_usb_init();
- break;
- case ALCHEMY_CPU_AU1300:
- au1300_usb_init();
- break;
- }
-
- register_syscore_ops(&alchemy_usb_pm_ops);
-
- return 0;
-}
-arch_initcall(alchemy_usb_init);
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
index 443da21d73c..df13d425e9c 100644
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -54,7 +54,7 @@ static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
return -ETIMEDOUT;
}
-static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
+static void bcma_hcd_4716wa(struct bcma_device *dev)
{
#ifdef CONFIG_BCMA_DRIVER_MIPS
/* Work around for 4716 failures. */
@@ -88,7 +88,7 @@ static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
}
/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
-static void __devinit bcma_hcd_init_chip(struct bcma_device *dev)
+static void bcma_hcd_init_chip(struct bcma_device *dev)
{
u32 tmp;
@@ -165,8 +165,7 @@ static const struct usb_ehci_pdata ehci_pdata = {
static const struct usb_ohci_pdata ohci_pdata = {
};
-static struct platform_device * __devinit
-bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
+static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
{
struct platform_device *hci_dev;
struct resource hci_res[2];
@@ -212,7 +211,7 @@ err_alloc:
return ERR_PTR(ret);
}
-static int __devinit bcma_hcd_probe(struct bcma_device *dev)
+static int bcma_hcd_probe(struct bcma_device *dev)
{
int err;
u16 chipid_top;
@@ -266,7 +265,7 @@ err_free_usb_dev:
return err;
}
-static void __devexit bcma_hcd_remove(struct bcma_device *dev)
+static void bcma_hcd_remove(struct bcma_device *dev)
{
struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
struct platform_device *ohci_dev = usb_dev->ohci_dev;
@@ -306,7 +305,7 @@ static int bcma_hcd_resume(struct bcma_device *dev)
#define bcma_hcd_resume NULL
#endif /* CONFIG_PM */
-static const struct bcma_device_id bcma_hcd_table[] __devinitconst = {
+static const struct bcma_device_id bcma_hcd_table[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
@@ -316,7 +315,7 @@ static struct bcma_driver bcma_hcd_driver = {
.name = KBUILD_MODNAME,
.id_table = bcma_hcd_table,
.probe = bcma_hcd_probe,
- .remove = __devexit_p(bcma_hcd_remove),
+ .remove = bcma_hcd_remove,
.shutdown = bcma_hcd_shutdown,
.suspend = bcma_hcd_suspend,
.resume = bcma_hcd_resume,
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 411bb74152e..27639487f7a 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -53,18 +53,11 @@ static void atmel_stop_ehci(struct platform_device *pdev)
static int ehci_atmel_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
/* registers start at offset 0x0 */
ehci->caps = hcd->regs;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_atmel_hc_driver = {
@@ -104,7 +97,7 @@ static const struct hc_driver ehci_atmel_hc_driver = {
static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev)
+static int ehci_atmel_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
const struct hc_driver *driver = &ehci_atmel_hc_driver;
@@ -189,7 +182,7 @@ fail_create_hcd:
return retval;
}
-static int __devexit ehci_atmel_drv_remove(struct platform_device *pdev)
+static int ehci_atmel_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -214,7 +207,7 @@ MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids);
static struct platform_driver ehci_atmel_driver = {
.probe = ehci_atmel_drv_probe,
- .remove = __devexit_p(ehci_atmel_drv_remove),
+ .remove = ehci_atmel_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.name = "atmel-ehci",
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
deleted file mode 100644
index 65c945eb414..00000000000
--- a/drivers/usb/host/ehci-au1xxx.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * EHCI HCD (Host Controller Driver) for USB.
- *
- * Bus Glue for AMD Alchemy Au1xxx
- *
- * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
- *
- * Modified for AMD Alchemy Au1200 EHC
- * by K.Boge <karsten.boge@amd.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach-au1x00/au1000.h>
-
-
-extern int usb_disabled(void);
-
-static int au1xxx_ehci_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
-
- ehci->caps = hcd->regs;
- ret = ehci_setup(hcd);
-
- ehci->need_io_watchdog = 0;
- return ret;
-}
-
-static const struct hc_driver ehci_au1xxx_hc_driver = {
- .description = hcd_name,
- .product_desc = "Au1xxx EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- *
- * FIXME -- ehci_init() doesn't do enough here.
- * See ehci-ppc-soc for a complete implementation.
- */
- .reset = au1xxx_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 int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ");
- return -ENOMEM;
- }
- hcd = usb_create_hcd(&ehci_au1xxx_hc_driver, &pdev->dev, "Au1xxx");
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (!hcd->regs) {
- pr_debug("devm_request_and_ioremap failed");
- ret = -ENOMEM;
- goto err1;
- }
-
- if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) {
- printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
- ret = -ENODEV;
- goto err1;
- }
-
- ret = usb_add_hcd(hcd, pdev->resource[1].start,
- IRQF_SHARED);
- if (ret == 0) {
- platform_set_drvdata(pdev, hcd);
- return ret;
- }
-
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- bool do_wakeup = device_may_wakeup(dev);
- int rc;
-
- rc = ehci_suspend(hcd, do_wakeup);
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
-
- return rc;
-}
-
-static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
-
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
- ehci_resume(hcd, false);
-
- return 0;
-}
-
-static const struct dev_pm_ops au1xxx_ehci_pmops = {
- .suspend = ehci_hcd_au1xxx_drv_suspend,
- .resume = ehci_hcd_au1xxx_drv_resume,
-};
-
-#define AU1XXX_EHCI_PMOPS &au1xxx_ehci_pmops
-
-#else
-#define AU1XXX_EHCI_PMOPS NULL
-#endif
-
-static struct platform_driver ehci_hcd_au1xxx_driver = {
- .probe = ehci_hcd_au1xxx_drv_probe,
- .remove = ehci_hcd_au1xxx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "au1xxx-ehci",
- .owner = THIS_MODULE,
- .pm = AU1XXX_EHCI_PMOPS,
- }
-};
-
-MODULE_ALIAS("platform:au1xxx-ehci");
diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c
deleted file mode 100644
index d91708d2e72..00000000000
--- a/drivers/usb/host/ehci-cns3xxx.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2008 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/atomic.h>
-#include <mach/cns3xxx.h>
-#include <mach/pm.h>
-
-static int cns3xxx_ehci_init(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- *
- * Set USB AHB INCR length to 16
- */
- if (atomic_inc_return(&usb_pwr_ref) == 1) {
- cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
- cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
- cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
- __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
- MISC_CHIP_CONFIG_REG);
- }
-
- ehci->caps = hcd->regs;
-
- hcd->has_tt = 0;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
-static const struct hc_driver cns3xxx_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "CNS3XXX EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
- .reset = cns3xxx_ehci_init,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
- .get_frame_number = ehci_get_frame,
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
-#endif
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int cns3xxx_ehci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &cns3xxx_ehci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "Found HC with no IRQ.\n");
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "Found HC with no register addr.\n");
- retval = -ENODEV;
- goto err1;
- }
-
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err1;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval == 0)
- return retval;
-
-err1:
- usb_put_hcd(hcd);
-
- return retval;
-}
-
-static int cns3xxx_ehci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- */
- if (atomic_dec_return(&usb_pwr_ref) == 0)
- cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
-
- usb_put_hcd(hcd);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:cns3xxx-ehci");
-
-static struct platform_driver cns3xxx_ehci_driver = {
- .probe = cns3xxx_ehci_probe,
- .remove = cns3xxx_ehci_remove,
- .driver = {
- .name = "cns3xxx-ehci",
- },
-};
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 1599806e3d4..70b496dc18a 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -18,21 +18,6 @@
/* this file is part of ehci-hcd.c */
-#define ehci_dbg(ehci, fmt, args...) \
- dev_dbg (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_err(ehci, fmt, args...) \
- dev_err (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_info(ehci, fmt, args...) \
- dev_info (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_warn(ehci, fmt, args...) \
- dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-
-#ifdef VERBOSE_DEBUG
-# define ehci_vdbg ehci_dbg
-#else
- static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {}
-#endif
-
#ifdef DEBUG
/* check the values in the HCSPARAMS register
@@ -352,11 +337,6 @@ 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_lpm_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-static ssize_t debug_lpm_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos);
-static int debug_lpm_close(struct inode *inode, struct file *file);
static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
static int debug_close(struct inode *, struct file *);
@@ -382,14 +362,6 @@ static const struct file_operations debug_registers_fops = {
.release = debug_close,
.llseek = default_llseek,
};
-static const struct file_operations debug_lpm_fops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = debug_lpm_read,
- .write = debug_lpm_write,
- .release = debug_lpm_close,
- .llseek = noop_llseek,
-};
static struct dentry *ehci_debug_root;
@@ -971,86 +943,6 @@ static int debug_registers_open(struct inode *inode, struct file *file)
return file->private_data ? 0 : -ENOMEM;
}
-static int debug_lpm_close(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static ssize_t debug_lpm_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- /* TODO: show lpm stats */
- return 0;
-}
-
-static ssize_t debug_lpm_write(struct file *file, const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct usb_hcd *hcd;
- struct ehci_hcd *ehci;
- char buf[50];
- size_t len;
- u32 temp;
- unsigned long port;
- u32 __iomem *portsc ;
- u32 params;
-
- hcd = bus_to_hcd(file->private_data);
- ehci = hcd_to_ehci(hcd);
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
- if (len > 0 && buf[len - 1] == '\n')
- buf[len - 1] = '\0';
-
- if (strncmp(buf, "enable", 5) == 0) {
- if (strict_strtoul(buf + 7, 10, &port))
- return -EINVAL;
- params = ehci_readl(ehci, &ehci->caps->hcs_params);
- if (port > HCS_N_PORTS(params)) {
- ehci_dbg(ehci, "ERR: LPM on bad port %lu\n", port);
- return -ENODEV;
- }
- portsc = &ehci->regs->port_status[port-1];
- temp = ehci_readl(ehci, portsc);
- if (!(temp & PORT_DEV_ADDR)) {
- ehci_dbg(ehci, "LPM: no device attached\n");
- return -ENODEV;
- }
- temp |= PORT_LPM;
- ehci_writel(ehci, temp, portsc);
- printk(KERN_INFO "force enable LPM for port %lu\n", port);
- } else if (strncmp(buf, "hird=", 5) == 0) {
- unsigned long hird;
- if (strict_strtoul(buf + 5, 16, &hird))
- return -EINVAL;
- printk(KERN_INFO "setting hird %s %lu\n", buf + 6, hird);
- ehci->command = (ehci->command & ~CMD_HIRD) | (hird << 24);
- ehci_writel(ehci, ehci->command, &ehci->regs->command);
- } else if (strncmp(buf, "disable", 7) == 0) {
- if (strict_strtoul(buf + 8, 10, &port))
- return -EINVAL;
- params = ehci_readl(ehci, &ehci->caps->hcs_params);
- if (port > HCS_N_PORTS(params)) {
- ehci_dbg(ehci, "ERR: LPM off bad port %lu\n", port);
- return -ENODEV;
- }
- portsc = &ehci->regs->port_status[port-1];
- temp = ehci_readl(ehci, portsc);
- if (!(temp & PORT_DEV_ADDR)) {
- ehci_dbg(ehci, "ERR: no device attached\n");
- return -ENODEV;
- }
- temp &= ~PORT_LPM;
- ehci_writel(ehci, temp, portsc);
- printk(KERN_INFO "disabled LPM for port %lu\n", port);
- } else
- return -EOPNOTSUPP;
- return count;
-}
-
static inline void create_debug_files (struct ehci_hcd *ehci)
{
struct usb_bus *bus = &ehci_to_hcd(ehci)->self;
@@ -1071,10 +963,6 @@ static inline void create_debug_files (struct ehci_hcd *ehci)
&debug_registers_fops))
goto file_error;
- if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus,
- &debug_lpm_fops))
- goto file_error;
-
return;
file_error:
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 0d2f35ca93f..d81d2fcbff1 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -230,7 +230,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
switch (phy_mode) {
case FSL_USB2_PHY_ULPI:
- if (pdata->controller_ver) {
+ if (pdata->have_sysif_regs && pdata->controller_ver) {
/* controller version 1.6 or above */
setbits32(non_ehci + FSL_SOC_USB_CTRL,
ULPI_PHY_CLK_SEL);
@@ -251,7 +251,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
portsc |= PORT_PTS_PTW;
/* fall through */
case FSL_USB2_PHY_UTMI:
- if (pdata->controller_ver) {
+ if (pdata->have_sysif_regs && pdata->controller_ver) {
/* controller version 1.6 or above */
setbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN);
mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to
@@ -267,7 +267,8 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
break;
}
- if (pdata->controller_ver && (phy_mode == FSL_USB2_PHY_ULPI)) {
+ if (pdata->have_sysif_regs && pdata->controller_ver &&
+ (phy_mode == FSL_USB2_PHY_ULPI)) {
/* check PHY_CLK_VALID to get phy clk valid */
if (!spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) &
PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0)) {
@@ -278,7 +279,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
- if (phy_mode != FSL_USB2_PHY_ULPI)
+ if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs)
setbits32(non_ehci + FSL_SOC_USB_CTRL, USB_CTRL_USB_EN);
return 0;
@@ -349,7 +350,6 @@ static int ehci_fsl_reinit(struct ehci_hcd *ehci)
{
if (ehci_fsl_usb_setup(ehci))
return -EINVAL;
- ehci_port_power(ehci, 0);
return 0;
}
diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c
index 3180cb3624d..1fc89292f5d 100644
--- a/drivers/usb/host/ehci-grlib.c
+++ b/drivers/usb/host/ehci-grlib.c
@@ -34,22 +34,6 @@
#define GRUSBHC_HCIVERSION 0x0100 /* Known value of cap. reg. HCIVERSION */
-/* called during probe() after chip reset completes */
-static int ehci_grlib_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 1);
-
- return retval;
-}
-
-
static const struct hc_driver ehci_grlib_hc_driver = {
.description = hcd_name,
.product_desc = "GRLIB GRUSBHC EHCI",
@@ -64,7 +48,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
/*
* basic lifecycle operations
*/
- .reset = ehci_grlib_setup,
+ .reset = ehci_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
@@ -98,7 +82,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
};
-static int __devinit ehci_hcd_grlib_probe(struct platform_device *op)
+static int ehci_hcd_grlib_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6bf6c42481e..09537b2f100 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -39,7 +39,6 @@
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
-#include <linux/uaccess.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -75,10 +74,6 @@ static const char hcd_name [] = "ehci_hcd";
#undef VERBOSE_DEBUG
#undef EHCI_URB_TRACE
-#ifdef DEBUG
-#define EHCI_STATS
-#endif
-
/* magic numbers that can affect system performance */
#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
@@ -108,19 +103,39 @@ static bool ignore_oc = 0;
module_param (ignore_oc, bool, S_IRUGO);
MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
-/* for link power management(LPM) feature */
-static unsigned int hird;
-module_param(hird, int, S_IRUGO);
-MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
-
#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
/*-------------------------------------------------------------------------*/
#include "ehci.h"
-#include "ehci-dbg.c"
#include "pci-quirks.h"
+/*
+ * The MosChip MCS9990 controller updates its microframe counter
+ * a little before the frame counter, and occasionally we will read
+ * the invalid intermediate value. Avoid problems by checking the
+ * microframe number (the low-order 3 bits); if they are 0 then
+ * re-read the register to get the correct value.
+ */
+static unsigned ehci_moschip_read_frame_index(struct ehci_hcd *ehci)
+{
+ unsigned uf;
+
+ uf = ehci_readl(ehci, &ehci->regs->frame_index);
+ if (unlikely((uf & 7) == 0))
+ uf = ehci_readl(ehci, &ehci->regs->frame_index);
+ return uf;
+}
+
+static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
+{
+ if (ehci->frame_index_bug)
+ return ehci_moschip_read_frame_index(ehci);
+ return ehci_readl(ehci, &ehci->regs->frame_index);
+}
+
+#include "ehci-dbg.c"
+
/*-------------------------------------------------------------------------*/
/*
@@ -293,7 +308,6 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
#include "ehci-timer.c"
#include "ehci-hub.c"
-#include "ehci-lpm.c"
#include "ehci-mem.c"
#include "ehci-q.c"
#include "ehci-sched.c"
@@ -353,24 +367,6 @@ static void ehci_shutdown(struct usb_hcd *hcd)
hrtimer_cancel(&ehci->hrtimer);
}
-static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
-{
- unsigned port;
-
- if (!HCS_PPC (ehci->hcs_params))
- return;
-
- ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down");
- for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
- (void) ehci_hub_control(ehci_to_hcd(ehci),
- is_on ? SetPortFeature : ClearPortFeature,
- USB_PORT_FEAT_POWER,
- port--, NULL, 0);
- /* Flush those writes */
- ehci_readl(ehci, &ehci->regs->command);
- msleep(20);
-}
-
/*-------------------------------------------------------------------------*/
/*
@@ -503,7 +499,7 @@ static int ehci_init(struct usb_hcd *hcd)
/* controllers may cache some of the periodic schedule ... */
if (HCC_ISOC_CACHE(hcc_params)) // full frame cache
- ehci->i_thresh = 2 + 8;
+ ehci->i_thresh = 0;
else // N microframes cached
ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
@@ -555,17 +551,6 @@ static int ehci_init(struct usb_hcd *hcd)
temp &= ~(3 << 2);
temp |= (EHCI_TUNE_FLS << 2);
}
- if (HCC_LPM(hcc_params)) {
- /* support link power management EHCI 1.1 addendum */
- ehci_dbg(ehci, "support lpm\n");
- ehci->has_lpm = 1;
- if (hird > 0xf) {
- ehci_dbg(ehci, "hird %d invalid, use default 0",
- hird);
- hird = 0;
- }
- temp |= hird << 24;
- }
ehci->command = temp;
/* Accept arbitrarily long scatter-gather lists */
@@ -660,7 +645,7 @@ static int ehci_run (struct usb_hcd *hcd)
return 0;
}
-static int ehci_setup(struct usb_hcd *hcd)
+int ehci_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
@@ -691,6 +676,7 @@ static int ehci_setup(struct usb_hcd *hcd)
return 0;
}
+EXPORT_SYMBOL_GPL(ehci_setup);
/*-------------------------------------------------------------------------*/
@@ -1096,7 +1082,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)
/* These routines handle the generic parts of controller suspend/resume */
-static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -1119,9 +1105,10 @@ static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
return 0;
}
+EXPORT_SYMBOL_GPL(ehci_suspend);
/* Returns 0 if power was preserved, 1 if power was lost */
-static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
+int ehci_resume(struct usb_hcd *hcd, bool hibernated)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -1177,53 +1164,93 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
ehci->rh_state = EHCI_RH_SUSPENDED;
spin_unlock_irq(&ehci->lock);
- /* here we "know" root ports should always stay powered */
- ehci_port_power(ehci, 1);
-
return 1;
}
+EXPORT_SYMBOL_GPL(ehci_resume);
#endif
/*-------------------------------------------------------------------------*/
/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
- * because its registers (and irq) are shared between host/gadget/otg
- * functions and in order to facilitate role switching we cannot
- * give the ehci driver exclusive access to those.
+ * Generic structure: This gets copied for platform drivers so that
+ * individual entries can be overridden as needed.
*/
-#ifndef CHIPIDEA_EHCI
+
+static const struct hc_driver ehci_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "EHCI Host Controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+
+ /*
+ * generic hardware linkage
+ */
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+
+ /*
+ * 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,
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+
+ /*
+ * 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,
+};
+
+void ehci_init_driver(struct hc_driver *drv,
+ const struct ehci_driver_overrides *over)
+{
+ /* Copy the generic table to drv and then apply the overrides */
+ *drv = ehci_hc_driver;
+
+ if (over) {
+ drv->hcd_priv_size += over->extra_priv_size;
+ if (over->reset)
+ drv->reset = over->reset;
+ }
+}
+EXPORT_SYMBOL_GPL(ehci_init_driver);
+
+/*-------------------------------------------------------------------------*/
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_LICENSE ("GPL");
-#ifdef CONFIG_PCI
-#include "ehci-pci.c"
-#define PCI_DRIVER ehci_pci_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_FSL
#include "ehci-fsl.c"
#define PLATFORM_DRIVER ehci_fsl_driver
#endif
-#ifdef CONFIG_USB_EHCI_MXC
-#include "ehci-mxc.c"
-#define PLATFORM_DRIVER ehci_mxc_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_SH
#include "ehci-sh.c"
#define PLATFORM_DRIVER ehci_hcd_sh_driver
#endif
-#ifdef CONFIG_MIPS_ALCHEMY
-#include "ehci-au1xxx.c"
-#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_HCD_OMAP
#include "ehci-omap.c"
#define PLATFORM_DRIVER ehci_hcd_omap_driver
@@ -1249,11 +1276,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_orion_driver
#endif
-#ifdef CONFIG_ARCH_IXP4XX
-#include "ehci-ixp4xx.c"
-#define PLATFORM_DRIVER ixp4xx_ehci_driver
-#endif
-
#ifdef CONFIG_USB_W90X900_EHCI
#include "ehci-w90x900.c"
#define PLATFORM_DRIVER ehci_hcd_w90x900_driver
@@ -1269,11 +1291,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_octeon_driver
#endif
-#ifdef CONFIG_USB_CNS3XXX_EHCI
-#include "ehci-cns3xxx.c"
-#define PLATFORM_DRIVER cns3xxx_ehci_driver
-#endif
-
#ifdef CONFIG_ARCH_VT8500
#include "ehci-vt8500.c"
#define PLATFORM_DRIVER vt8500_ehci_driver
@@ -1314,34 +1331,24 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_grlib_driver
#endif
-#ifdef CONFIG_CPU_XLR
-#include "ehci-xls.c"
-#define PLATFORM_DRIVER ehci_xls_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_MV
#include "ehci-mv.c"
#define PLATFORM_DRIVER ehci_mv_driver
#endif
-#ifdef CONFIG_MACH_LOONGSON1
-#include "ehci-ls1x.c"
-#define PLATFORM_DRIVER ehci_ls1x_driver
-#endif
-
#ifdef CONFIG_MIPS_SEAD3
#include "ehci-sead3.c"
#define PLATFORM_DRIVER ehci_hcd_sead3_driver
#endif
-#ifdef CONFIG_USB_EHCI_HCD_PLATFORM
-#include "ehci-platform.c"
-#define PLATFORM_DRIVER ehci_platform_driver
-#endif
-
-#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
- !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
- !defined(XILINX_OF_PLATFORM_DRIVER)
+#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \
+ !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \
+ !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \
+ !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
+ !defined(PLATFORM_DRIVER) && \
+ !defined(PS3_SYSTEM_BUS_DRIVER) && \
+ !defined(OF_PLATFORM_DRIVER) && \
+ !defined(XILINX_OF_PLATFORM_DRIVER)
#error "missing bus glue for ehci-hcd"
#endif
@@ -1378,12 +1385,6 @@ static int __init ehci_hcd_init(void)
goto clean0;
#endif
-#ifdef PCI_DRIVER
- retval = pci_register_driver(&PCI_DRIVER);
- if (retval < 0)
- goto clean1;
-#endif
-
#ifdef PS3_SYSTEM_BUS_DRIVER
retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
if (retval < 0)
@@ -1415,10 +1416,6 @@ clean3:
ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
clean2:
#endif
-#ifdef PCI_DRIVER
- pci_unregister_driver(&PCI_DRIVER);
-clean1:
-#endif
#ifdef PLATFORM_DRIVER
platform_driver_unregister(&PLATFORM_DRIVER);
clean0:
@@ -1444,9 +1441,6 @@ static void __exit ehci_hcd_cleanup(void)
#ifdef PLATFORM_DRIVER
platform_driver_unregister(&PLATFORM_DRIVER);
#endif
-#ifdef PCI_DRIVER
- pci_unregister_driver(&PCI_DRIVER);
-#endif
#ifdef PS3_SYSTEM_BUS_DRIVER
ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
#endif
@@ -1456,5 +1450,3 @@ static void __exit ehci_hcd_cleanup(void)
clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
}
module_exit(ehci_hcd_cleanup);
-
-#endif /* CHIPIDEA_EHCI */
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 914ce9370e7..4ccb97c0678 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -56,6 +56,19 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
if (!ehci->owned_ports)
return;
+ /* Make sure the ports are powered */
+ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ 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);
+ }
+ }
+ }
+
/* Give the connections some time to appear */
msleep(20);
@@ -384,11 +397,24 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
ehci_writel(ehci, ehci->command, &ehci->regs->command);
ehci->rh_state = EHCI_RH_RUNNING;
- /* Some controller/firmware combinations need a delay during which
- * they set up the port statuses. See Bugzilla #8190. */
- spin_unlock_irq(&ehci->lock);
- msleep(8);
- spin_lock_irq(&ehci->lock);
+ /*
+ * According to Bugzilla #8190, the port status for some controllers
+ * will be wrong without a delay. At their wrong status, the port
+ * is enabled, but not suspended neither resumed.
+ */
+ i = HCS_N_PORTS(ehci->hcs_params);
+ while (i--) {
+ temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
+ if ((temp & PORT_PE) &&
+ !(temp & (PORT_SUSPEND | PORT_RESUME))) {
+ ehci_dbg(ehci, "Port status(0x%x) is wrong\n", temp);
+ spin_unlock_irq(&ehci->lock);
+ msleep(8);
+ spin_lock_irq(&ehci->lock);
+ break;
+ }
+ }
+
if (ehci->shutdown)
goto shutdown;
@@ -764,11 +790,6 @@ static int ehci_hub_control (
status_reg);
break;
case USB_PORT_FEAT_C_CONNECTION:
- if (ehci->has_lpm) {
- /* clear PORTSC bits on disconnect */
- temp &= ~PORT_LPM;
- temp &= ~PORT_DEV_ADDR;
- }
ehci_writel(ehci, temp | PORT_CSC, status_reg);
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
@@ -1088,8 +1109,7 @@ error_exit:
return retval;
}
-static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
- int portnum)
+static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -1098,8 +1118,7 @@ static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
set_owner(ehci, --portnum, PORT_OWNER);
}
-static int __maybe_unused ehci_port_handed_over(struct usb_hcd *hcd,
- int portnum)
+static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
u32 __iomem *reg;
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c
deleted file mode 100644
index f224c0a48be..00000000000
--- a/drivers/usb/host/ehci-ixp4xx.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * IXP4XX EHCI Host Controller Driver
- *
- * Author: Vladimir Barinov <vbarinov@embeddedalley.com>
- *
- * Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/platform_device.h>
-
-static int ixp4xx_ehci_init(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval = 0;
-
- ehci->big_endian_desc = 1;
- ehci->big_endian_mmio = 1;
-
- ehci->caps = hcd->regs + 0x100;
-
- hcd->has_tt = 1;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
-static const struct hc_driver ixp4xx_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "IXP4XX EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
- .reset = ixp4xx_ehci_init,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
- .get_frame_number = ehci_get_frame,
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#if defined(CONFIG_PM)
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
-#endif
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ixp4xx_ehci_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &ixp4xx_ehci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd) {
- retval = -ENOMEM;
- goto fail_create_hcd;
- }
-
- 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_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto fail_request_resource;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval)
- goto fail_request_resource;
-
- return retval;
-
-fail_request_resource:
- usb_put_hcd(hcd);
-fail_create_hcd:
- dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
- return retval;
-}
-
-static int ixp4xx_ehci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:ixp4xx-ehci");
-
-static struct platform_driver ixp4xx_ehci_driver = {
- .probe = ixp4xx_ehci_probe,
- .remove = ixp4xx_ehci_remove,
- .driver = {
- .name = "ixp4xx-ehci",
- },
-};
diff --git a/drivers/usb/host/ehci-lpm.c b/drivers/usb/host/ehci-lpm.c
deleted file mode 100644
index 2111627a19d..00000000000
--- a/drivers/usb/host/ehci-lpm.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ehci-lpm.c EHCI HCD LPM support code
- * Copyright (c) 2008 - 2010, Intel Corporation.
- * Author: Jacob Pan <jacob.jun.pan@intel.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* this file is part of ehci-hcd.c */
-static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci,
- int dev_addr, int port_num)
-{
- u32 __iomem portsc;
-
- ehci_dbg(ehci, "set dev address %d for port %d\n", dev_addr, port_num);
- if (port_num > HCS_N_PORTS(ehci->hcs_params)) {
- ehci_dbg(ehci, "invalid port number %d\n", port_num);
- return -ENODEV;
- }
- portsc = ehci_readl(ehci, &ehci->regs->port_status[port_num-1]);
- portsc &= ~PORT_DEV_ADDR;
- portsc |= dev_addr<<25;
- ehci_writel(ehci, portsc, &ehci->regs->port_status[port_num-1]);
- return 0;
-}
-
-/*
- * this function is used to check if the device support LPM
- * if yes, mark the PORTSC register with PORT_LPM bit
- */
-static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port)
-{
- u32 __iomem *portsc ;
- u32 val32;
- int retval;
-
- portsc = &ehci->regs->port_status[port-1];
- val32 = ehci_readl(ehci, portsc);
- if (!(val32 & PORT_DEV_ADDR)) {
- ehci_dbg(ehci, "LPM: no device attached\n");
- return -ENODEV;
- }
- val32 |= PORT_LPM;
- ehci_writel(ehci, val32, portsc);
- msleep(5);
- val32 |= PORT_SUSPEND;
- ehci_dbg(ehci, "Sending LPM 0x%08x to port %d\n", val32, port);
- ehci_writel(ehci, val32, portsc);
- /* wait for ACK */
- msleep(10);
- retval = handshake(ehci, &ehci->regs->port_status[port-1], PORT_SSTS,
- PORTSC_SUSPEND_STS_ACK, 125);
- dbg_port(ehci, "LPM", port, val32);
- if (retval != -ETIMEDOUT) {
- ehci_dbg(ehci, "LPM: device ACK for LPM\n");
- val32 |= PORT_LPM;
- /*
- * now device should be in L1 sleep, let's wake up the device
- * so that we can complete enumeration.
- */
- ehci_writel(ehci, val32, portsc);
- msleep(10);
- val32 |= PORT_RESUME;
- ehci_writel(ehci, val32, portsc);
- } else {
- ehci_dbg(ehci, "LPM: device does not ACK, disable LPM %d\n",
- retval);
- val32 &= ~PORT_LPM;
- retval = -ETIMEDOUT;
- ehci_writel(ehci, val32, portsc);
- }
-
- return retval;
-}
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c
deleted file mode 100644
index ca759652626..00000000000
--- a/drivers/usb/host/ehci-ls1x.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Bus Glue for Loongson LS1X built-in EHCI controller.
- *
- * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-
-#include <linux/platform_device.h>
-
-static int ehci_ls1x_reset(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
-
- ehci->caps = hcd->regs;
-
- ret = ehci_setup(hcd);
- if (ret)
- return ret;
-
- ehci_port_power(ehci, 0);
-
- return 0;
-}
-
-static const struct hc_driver ehci_ls1x_hc_driver = {
- .description = hcd_name,
- .product_desc = "LOONGSON1 EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_ls1x_reset,
- .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,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int irq;
- int ret;
-
- pr_debug("initializing loongson1 ehci USB Controller\n");
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- irq = res->start;
-
- 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));
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev,
- dev_name(&pdev->dev));
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- ret = -EFAULT;
- goto err_put_hcd;
- }
-
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret)
- goto err_put_hcd;
-
- return ret;
-
-err_put_hcd:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ehci_hcd_ls1x_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ehci_ls1x_driver = {
- .probe = ehci_hcd_ls1x_probe,
- .remove = ehci_hcd_ls1x_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ls1x-ehci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci");
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 4af4dc5b618..88a49c87e74 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -53,7 +53,6 @@ static int ehci_msm_reset(struct usb_hcd *hcd)
/* Disable streaming mode and select host mode */
writel(0x13, USB_USBMODE);
- ehci_port_power(ehci, 1);
return 0;
}
@@ -174,7 +173,7 @@ put_hcd:
return ret;
}
-static int __devexit ehci_msm_remove(struct platform_device *pdev)
+static int ehci_msm_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -221,7 +220,7 @@ static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
static struct platform_driver ehci_msm_driver = {
.probe = ehci_msm_probe,
- .remove = __devexit_p(ehci_msm_remove),
+ .remove = ehci_msm_remove,
.driver = {
.name = "msm_hsusb_host",
.pm = &ehci_msm_dev_pm_ops,
diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c
index f7bfc0b898b..6c56297ea16 100644
--- a/drivers/usb/host/ehci-mv.c
+++ b/drivers/usb/host/ehci-mv.c
@@ -43,7 +43,7 @@ static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv)
unsigned int i;
for (i = 0; i < ehci_mv->clknum; i++)
- clk_enable(ehci_mv->clk[i]);
+ clk_prepare_enable(ehci_mv->clk[i]);
}
static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv)
@@ -51,7 +51,7 @@ static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv)
unsigned int i;
for (i = 0; i < ehci_mv->clknum; i++)
- clk_disable(ehci_mv->clk[i]);
+ clk_disable_unprepare(ehci_mv->clk[i]);
}
static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv)
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 4a08fc0b27c..dedb80bb8d4 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -17,84 +17,38 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
-#include <mach/hardware.h>
#include <linux/platform_data/usb-ehci-mxc.h>
#include <asm/mach-types.h>
+#include "ehci.h"
+
+#define DRIVER_DESC "Freescale On-Chip EHCI Host driver"
+
+static const char hcd_name[] = "ehci-mxc";
+
#define ULPI_VIEWPORT_OFFSET 0x170
struct ehci_mxc_priv {
struct clk *usbclk, *ahbclk, *phyclk;
- struct usb_hcd *hcd;
};
-/* called during probe() after chip reset completes */
-static int ehci_mxc_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- hcd->has_tt = 1;
+static struct hc_driver __read_mostly ehci_mxc_hc_driver;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
- return 0;
-}
-
-static const struct hc_driver ehci_mxc_hc_driver = {
- .description = hcd_name,
- .product_desc = "Freescale On-Chip EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_USB2 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_mxc_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 const struct ehci_driver_overrides ehci_mxc_overrides __initdata = {
+ .extra_priv_size = sizeof(struct ehci_mxc_priv),
};
static int ehci_mxc_drv_probe(struct platform_device *pdev)
@@ -121,12 +75,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
if (!hcd)
return -ENOMEM;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- ret = -ENOMEM;
- goto err_alloc;
- }
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "Found HC with no register addr. Check setup!\n");
@@ -144,6 +92,10 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
goto err_alloc;
}
+ hcd->has_tt = 1;
+ ehci = hcd_to_ehci(hcd);
+ priv = (struct ehci_mxc_priv *) ehci->priv;
+
/* enable clocks */
priv->usbclk = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(priv->usbclk)) {
@@ -178,8 +130,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
mdelay(10);
}
- ehci = hcd_to_ehci(hcd);
-
/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
ehci->regs = hcd->regs + 0x100 +
@@ -207,8 +157,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
}
}
- priv->hcd = hcd;
- platform_set_drvdata(pdev, priv);
+ platform_set_drvdata(pdev, hcd);
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret)
@@ -253,8 +202,11 @@ err_alloc:
static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
{
struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
- struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
- struct usb_hcd *hcd = priv->hcd;
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct ehci_mxc_priv *priv = (struct ehci_mxc_priv *) ehci->priv;
+
+ usb_remove_hcd(hcd);
if (pdata && pdata->exit)
pdata->exit(pdev);
@@ -262,23 +214,20 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
if (pdata->otg)
usb_phy_shutdown(pdata->otg);
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
clk_disable_unprepare(priv->usbclk);
clk_disable_unprepare(priv->ahbclk);
if (priv->phyclk)
clk_disable_unprepare(priv->phyclk);
+ usb_put_hcd(hcd);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
static void ehci_mxc_drv_shutdown(struct platform_device *pdev)
{
- struct ehci_mxc_priv *priv = platform_get_drvdata(pdev);
- struct usb_hcd *hcd = priv->hcd;
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd);
@@ -288,9 +237,31 @@ MODULE_ALIAS("platform:mxc-ehci");
static struct platform_driver ehci_mxc_driver = {
.probe = ehci_mxc_drv_probe,
- .remove = __exit_p(ehci_mxc_drv_remove),
+ .remove = ehci_mxc_drv_remove,
.shutdown = ehci_mxc_drv_shutdown,
.driver = {
.name = "mxc-ehci",
},
};
+
+static int __init ehci_mxc_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ehci_init_driver(&ehci_mxc_hc_driver, &ehci_mxc_overrides);
+ return platform_driver_register(&ehci_mxc_driver);
+}
+module_init(ehci_mxc_init);
+
+static void __exit ehci_mxc_cleanup(void)
+{
+ platform_driver_unregister(&ehci_mxc_driver);
+}
+module_exit(ehci_mxc_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Sascha Hauer");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c
index ba26957abf4..a89750fff4f 100644
--- a/drivers/usb/host/ehci-octeon.c
+++ b/drivers/usb/host/ehci-octeon.c
@@ -159,9 +159,6 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hcd);
- /* root ports should always stay powered */
- ehci_port_power(ehci, 1);
-
return 0;
err3:
ehci_octeon_stop();
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index d7fe287d067..ac17a7c3a0c 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -39,12 +39,13 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/usb/ulpi.h>
-#include <plat/usb.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/gpio.h>
#include <linux/clk.h>
+#include <linux/platform_data/usb-omap.h>
+
/* EHCI Register Set */
#define EHCI_INSNREG04 (0xA0)
#define EHCI_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
@@ -146,9 +147,6 @@ static int omap_ehci_init(struct usb_hcd *hcd)
gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1);
}
- /* root ports should always stay powered */
- ehci_port_power(ehci, 1);
-
return rc;
}
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 9c2717d6673..914a3ecfb5d 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -14,6 +14,9 @@
#include <linux/mbus.h>
#include <linux/clk.h>
#include <linux/platform_data/usb-ehci-orion.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
#define rdl(off) __raw_readl(hcd->regs + (off))
#define wrl(off, val) __raw_writel((val), hcd->regs + (off))
@@ -101,20 +104,6 @@ static void orion_usb_phy_v1_setup(struct usb_hcd *hcd)
wrl(USB_MODE, 0x13);
}
-static int ehci_orion_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
static const struct hc_driver ehci_orion_hc_driver = {
.description = hcd_name,
.product_desc = "Marvell Orion EHCI",
@@ -129,7 +118,7 @@ static const struct hc_driver ehci_orion_hc_driver = {
/*
* basic lifecycle operations
*/
- .reset = ehci_orion_setup,
+ .reset = ehci_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
@@ -160,7 +149,7 @@ static const struct hc_driver ehci_orion_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static void __devinit
+static void
ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
const struct mbus_dram_target_info *dram)
{
@@ -181,7 +170,9 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
}
}
-static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
+static u64 ehci_orion_dma_mask = DMA_BIT_MASK(32);
+
+static int ehci_orion_drv_probe(struct platform_device *pdev)
{
struct orion_ehci_data *pd = pdev->dev.platform_data;
const struct mbus_dram_target_info *dram;
@@ -191,13 +182,17 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
struct clk *clk;
void __iomem *regs;
int irq, err;
+ enum orion_ehci_phy_ver phy_version;
if (usb_disabled())
return -ENODEV;
pr_debug("Initializing Orion-SoC USB Host Controller\n");
- irq = platform_get_irq(pdev, 0);
+ if (pdev->dev.of_node)
+ irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ else
+ irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(&pdev->dev,
"Found HC with no IRQ. Check %s setup!\n",
@@ -215,6 +210,14 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
goto err1;
}
+ /*
+ * Right now device-tree probed devices don't get dma_mask
+ * set. Since shared usb code relies on it, set it here for
+ * now. Once we have dma capability bindings this can go away.
+ */
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &ehci_orion_dma_mask;
+
if (!request_mem_region(res->start, resource_size(res),
ehci_orion_hc_driver.description)) {
dev_dbg(&pdev->dev, "controller already in use\n");
@@ -262,7 +265,12 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
/*
* setup Orion USB controller.
*/
- switch (pd->phy_version) {
+ if (pdev->dev.of_node)
+ phy_version = EHCI_PHY_NA;
+ else
+ phy_version = pd->phy_version;
+
+ switch (phy_version) {
case EHCI_PHY_NA: /* dont change USB phy settings */
break;
case EHCI_PHY_ORION:
@@ -317,9 +325,19 @@ static int __exit ehci_orion_drv_remove(struct platform_device *pdev)
MODULE_ALIAS("platform:orion-ehci");
+static const struct of_device_id ehci_orion_dt_ids[] = {
+ { .compatible = "marvell,orion-ehci", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ehci_orion_dt_ids);
+
static struct platform_driver ehci_orion_driver = {
.probe = ehci_orion_drv_probe,
.remove = __exit_p(ehci_orion_drv_remove),
.shutdown = usb_hcd_platform_shutdown,
- .driver.name = "orion-ehci",
+ .driver = {
+ .name = "orion-ehci",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ehci_orion_dt_ids),
+ },
};
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 2cb7d370c4e..170b9399e09 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -18,9 +18,18 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef CONFIG_PCI
-#error "This file is PCI bus glue. CONFIG_PCI must be defined."
-#endif
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ehci.h"
+#include "pci-quirks.h"
+
+#define DRIVER_DESC "EHCI PCI platform driver"
+
+static const char hcd_name[] = "ehci-pci";
/* defined here to avoid adding to pci_ids.h for single instance use */
#define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70
@@ -103,7 +112,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
}
break;
case PCI_VENDOR_ID_INTEL:
- ehci->fs_i_thresh = 1;
if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB)
hcd->has_tt = 1;
break;
@@ -192,6 +200,26 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
break;
}
+ /* optional debug port, normally in the first BAR */
+ temp = pci_find_capability(pdev, PCI_CAP_ID_DBG);
+ if (temp) {
+ pci_read_config_dword(pdev, temp, &temp);
+ temp >>= 16;
+ if (((temp >> 13) & 7) == 1) {
+ u32 hcs_params = ehci_readl(ehci,
+ &ehci->caps->hcs_params);
+
+ temp &= 0x1fff;
+ ehci->debug = hcd->regs + temp;
+ temp = ehci_readl(ehci, &ehci->debug->control);
+ ehci_info(ehci, "debug port %d%s\n",
+ HCS_DEBUG_PORT(hcs_params),
+ (temp & DBGP_ENABLED) ? " IN USE" : "");
+ if (!(temp & DBGP_ENABLED))
+ ehci->debug = NULL;
+ }
+ }
+
retval = ehci_setup(hcd);
if (retval)
return retval;
@@ -203,11 +231,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
break;
case PCI_VENDOR_ID_INTEL:
ehci->need_io_watchdog = 0;
- if (pdev->device == 0x0806 || pdev->device == 0x0811
- || pdev->device == 0x0829) {
- ehci_info(ehci, "disable lpm for langwell/penwell\n");
- ehci->has_lpm = 0;
- }
break;
case PCI_VENDOR_ID_NVIDIA:
switch (pdev->device) {
@@ -217,8 +240,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
* devices with PPCD enabled.
*/
case 0x0d9d:
- ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
- ehci->has_lpm = 0;
+ ehci_info(ehci, "disable ppcd for nvidia mcp89\n");
ehci->has_ppcd = 0;
ehci->command &= ~CMD_PPCEE;
break;
@@ -226,25 +248,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
break;
}
- /* optional debug port, normally in the first BAR */
- temp = pci_find_capability(pdev, 0x0a);
- if (temp) {
- pci_read_config_dword(pdev, temp, &temp);
- temp >>= 16;
- if ((temp & (3 << 13)) == (1 << 13)) {
- temp &= 0x1fff;
- ehci->debug = hcd->regs + temp;
- temp = ehci_readl(ehci, &ehci->debug->control);
- ehci_info(ehci, "debug port %d%s\n",
- HCS_DEBUG_PORT(ehci->hcs_params),
- (temp & DBGP_ENABLED)
- ? " IN USE"
- : "");
- if (!(temp & DBGP_ENABLED))
- ehci->debug = NULL;
- }
- }
-
/* at least the Genesys GL880S needs fixup here */
temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
temp &= 0x0f;
@@ -304,7 +307,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
#endif
- ehci_port_power(ehci, 1);
retval = ehci_pci_reinit(ehci, pdev);
done:
return retval;
@@ -323,18 +325,14 @@ done:
* Also they depend on separate root hub suspend/resume.
*/
-static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
-{
- return ehci_suspend(hcd, do_wakeup);
-}
-
static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
{
return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
pdev->vendor == PCI_VENDOR_ID_INTEL &&
(pdev->device == 0x1E26 ||
pdev->device == 0x8C2D ||
- pdev->device == 0x8C26);
+ pdev->device == 0x8C26 ||
+ pdev->device == 0x9C26);
}
static void ehci_enable_xhci_companion(void)
@@ -378,76 +376,17 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
(void) ehci_pci_reinit(ehci, pdev);
return 0;
}
-#endif
-static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int rc = 0;
-
- if (!udev->parent) /* udev is root hub itself, impossible */
- rc = -1;
- /* we only support lpm device connected to root hub yet */
- if (ehci->has_lpm && !udev->parent->parent) {
- rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
- if (!rc)
- rc = ehci_lpm_check(ehci, udev->portnum);
- }
- return rc;
-}
+#else
-static const struct hc_driver ehci_pci_hc_driver = {
- .description = hcd_name,
- .product_desc = "EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
+#define ehci_suspend NULL
+#define ehci_pci_resume NULL
+#endif /* CONFIG_PM */
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
+static struct hc_driver __read_mostly ehci_pci_hc_driver;
- /*
- * basic lifecycle operations
- */
+static const struct ehci_driver_overrides pci_overrides __initdata = {
.reset = ehci_pci_setup,
- .start = ehci_run,
-#ifdef CONFIG_PM
- .pci_suspend = ehci_pci_suspend,
- .pci_resume = ehci_pci_resume,
-#endif
- .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,
-
- /*
- * call back when device connected and addressed
- */
- .update_device = ehci_update_device,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
/*-------------------------------------------------------------------------*/
@@ -480,3 +419,31 @@ static struct pci_driver ehci_pci_driver = {
},
#endif
};
+
+static int __init ehci_pci_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ehci_init_driver(&ehci_pci_hc_driver, &pci_overrides);
+
+ /* Entries for the PCI suspend/resume callbacks are special */
+ ehci_pci_hc_driver.pci_suspend = ehci_suspend;
+ ehci_pci_hc_driver.pci_resume = ehci_pci_resume;
+
+ return pci_register_driver(&ehci_pci_driver);
+}
+module_init(ehci_pci_init);
+
+static void __exit ehci_pci_cleanup(void)
+{
+ pci_unregister_driver(&ehci_pci_driver);
+}
+module_exit(ehci_pci_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("David Brownell");
+MODULE_AUTHOR("Alan Stern");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 764e0100b6f..58fa0c90c7c 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -18,9 +18,21 @@
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
+#include <linux/kernel.h>
+#include <linux/hrtimer.h>
+#include <linux/io.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
#include <linux/usb/ehci_pdriver.h>
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI generic platform driver"
+
+static const char hcd_name[] = "ehci-platform";
+
static int ehci_platform_reset(struct usb_hcd *hcd)
{
struct platform_device *pdev = to_platform_device(hcd->self.controller);
@@ -38,47 +50,18 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
if (retval)
return retval;
- if (pdata->port_power_on)
- ehci_port_power(ehci, 1);
- if (pdata->port_power_off)
- ehci_port_power(ehci, 0);
-
+ if (pdata->no_io_watchdog)
+ ehci->need_io_watchdog = 0;
return 0;
}
-static const struct hc_driver ehci_platform_hc_driver = {
- .description = hcd_name,
- .product_desc = "Generic Platform EHCI Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- .reset = ehci_platform_reset,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
+static struct hc_driver __read_mostly ehci_platform_hc_driver;
- .get_frame_number = ehci_get_frame,
-
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#if defined(CONFIG_PM)
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
-#endif
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+static const struct ehci_driver_overrides platform_overrides __initdata = {
+ .reset = ehci_platform_reset,
};
-static int __devinit ehci_platform_probe(struct platform_device *dev)
+static int ehci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
@@ -96,12 +79,12 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
irq = platform_get_irq(dev, 0);
if (irq < 0) {
- pr_err("no irq provided");
+ dev_err(&dev->dev, "no irq provided");
return irq;
}
res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res_mem) {
- pr_err("no memory recourse provided");
+ dev_err(&dev->dev, "no memory resource provided");
return -ENXIO;
}
@@ -121,29 +104,19 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_err("controller already in use");
- err = -EBUSY;
- goto err_put_hcd;
- }
-
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_request_and_ioremap(&dev->dev, res_mem);
if (!hcd->regs) {
err = -ENOMEM;
- goto err_release_region;
+ goto err_put_hcd;
}
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_iounmap;
+ goto err_put_hcd;
platform_set_drvdata(dev, hcd);
return err;
-err_iounmap:
- iounmap(hcd->regs);
-err_release_region:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put_hcd:
usb_put_hcd(hcd);
err_power:
@@ -153,14 +126,12 @@ err_power:
return err;
}
-static int __devexit ehci_platform_remove(struct platform_device *dev)
+static int ehci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct usb_ehci_pdata *pdata = dev->dev.platform_data;
usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
platform_set_drvdata(dev, NULL);
@@ -225,7 +196,7 @@ static const struct dev_pm_ops ehci_platform_pm_ops = {
static struct platform_driver ehci_platform_driver = {
.id_table = ehci_platform_table,
.probe = ehci_platform_probe,
- .remove = __devexit_p(ehci_platform_remove),
+ .remove = ehci_platform_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.owner = THIS_MODULE,
@@ -233,3 +204,26 @@ static struct platform_driver ehci_platform_driver = {
.pm = &ehci_platform_pm_ops,
}
};
+
+static int __init ehci_platform_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ehci_init_driver(&ehci_platform_hc_driver, &platform_overrides);
+ return platform_driver_register(&ehci_platform_driver);
+}
+module_init(ehci_platform_init);
+
+static void __exit ehci_platform_cleanup(void)
+{
+ platform_driver_unregister(&ehci_platform_driver);
+}
+module_exit(ehci_platform_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_AUTHOR("Alan Stern");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c
index 087aee2a904..363890ee41d 100644
--- a/drivers/usb/host/ehci-pmcmsp.c
+++ b/drivers/usb/host/ehci-pmcmsp.c
@@ -90,7 +90,6 @@ static int ehci_msp_setup(struct usb_hcd *hcd)
return retval;
usb_hcd_tdi_set_mode(ehci);
- ehci_port_power(ehci, 0);
return retval;
}
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index fa937d05a02..45aceefd0c2 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -71,7 +71,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
* Fix: Enable Break Memory Transfer (BMT) in INSNREG3
*/
#define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0)
-static int __devinit
+static int
ppc44x_enable_bmt(struct device_node *dn)
{
__iomem u32 *insreg_virt;
@@ -87,7 +87,7 @@ ppc44x_enable_bmt(struct device_node *dn)
}
-static int __devinit ehci_hcd_ppc_of_probe(struct platform_device *op)
+static int ehci_hcd_ppc_of_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 45a356e9f13..df5925a4f0d 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -93,7 +93,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev)
+static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
{
int result;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 4b66374bdc8..3d989028c83 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -264,15 +264,9 @@ ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status)
__releases(ehci->lock)
__acquires(ehci->lock)
{
- if (likely (urb->hcpriv != NULL)) {
- struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
-
- /* S-mask in a QH means it's an interrupt urb */
- if ((qh->hw->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) {
-
- /* ... update hc-wide periodic stats (for usbfs) */
- ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
- }
+ if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+ /* ... update hc-wide periodic stats */
+ ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
}
if (unlikely(urb->unlinked)) {
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 85b74be202e..319dcfaa873 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -85,7 +85,7 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev)
static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
-static int __devinit s5p_ehci_probe(struct platform_device *pdev)
+static int s5p_ehci_probe(struct platform_device *pdev)
{
struct s5p_ehci_platdata *pdata;
struct s5p_ehci_hcd *s5p_ehci;
@@ -136,7 +136,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev)
goto fail_clk;
}
- err = clk_enable(s5p_ehci->clk);
+ err = clk_prepare_enable(s5p_ehci->clk);
if (err)
goto fail_clk;
@@ -183,13 +183,13 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev)
return 0;
fail_io:
- clk_disable(s5p_ehci->clk);
+ clk_disable_unprepare(s5p_ehci->clk);
fail_clk:
usb_put_hcd(hcd);
return err;
}
-static int __devexit s5p_ehci_remove(struct platform_device *pdev)
+static int s5p_ehci_remove(struct platform_device *pdev)
{
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
@@ -200,7 +200,7 @@ static int __devexit s5p_ehci_remove(struct platform_device *pdev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(s5p_ehci->clk);
+ clk_disable_unprepare(s5p_ehci->clk);
usb_put_hcd(hcd);
@@ -231,7 +231,7 @@ static int s5p_ehci_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(s5p_ehci->clk);
+ clk_disable_unprepare(s5p_ehci->clk);
return rc;
}
@@ -243,7 +243,7 @@ static int s5p_ehci_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
- clk_enable(s5p_ehci->clk);
+ clk_prepare_enable(s5p_ehci->clk);
if (pdata && pdata->phy_init)
pdata->phy_init(pdev, S5P_USB_PHY_HOST);
@@ -274,7 +274,7 @@ MODULE_DEVICE_TABLE(of, exynos_ehci_match);
static struct platform_driver s5p_ehci_driver = {
.probe = s5p_ehci_probe,
- .remove = __devexit_p(s5p_ehci_remove),
+ .remove = s5p_ehci_remove,
.shutdown = s5p_ehci_shutdown,
.driver = {
.name = "s5p-ehci",
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 7cf3da7babf..69ebee73c0c 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -36,29 +36,6 @@
static int ehci_get_frame (struct usb_hcd *hcd);
-#ifdef CONFIG_PCI
-
-static unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
-{
- unsigned uf;
-
- /*
- * The MosChip MCS9990 controller updates its microframe counter
- * a little before the frame counter, and occasionally we will read
- * the invalid intermediate value. Avoid problems by checking the
- * microframe number (the low-order 3 bits); if they are 0 then
- * re-read the register to get the correct value.
- */
- uf = ehci_readl(ehci, &ehci->regs->frame_index);
- if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0)))
- uf = ehci_readl(ehci, &ehci->regs->frame_index);
- return uf;
-}
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
/*
* periodic_next_shadow - return "next" pointer on shadow list
* @periodic: host pointer to qh/itd/sitd
@@ -1361,7 +1338,7 @@ sitd_slot_ok (
* given EHCI_TUNE_FLS and the slop). Or, write a smarter scheduler!
*/
-#define SCHEDULE_SLOP 80 /* microframes */
+#define SCHEDULING_DELAY 40 /* microframes */
static int
iso_stream_schedule (
@@ -1370,7 +1347,7 @@ iso_stream_schedule (
struct ehci_iso_stream *stream
)
{
- u32 now, next, start, period, span;
+ u32 now, base, next, start, period, span;
int status;
unsigned mod = ehci->periodic_size << 3;
struct ehci_iso_sched *sched = urb->hcpriv;
@@ -1382,62 +1359,72 @@ iso_stream_schedule (
span <<= 3;
}
- if (span > mod - SCHEDULE_SLOP) {
- ehci_dbg (ehci, "iso request %p too long\n", urb);
- status = -EFBIG;
- goto fail;
- }
-
now = ehci_read_frame_index(ehci) & (mod - 1);
/* Typical case: reuse current schedule, stream is still active.
* Hopefully there are no gaps from the host falling behind
- * (irq delays etc), but if there are we'll take the next
- * slot in the schedule, implicitly assuming URB_ISO_ASAP.
+ * (irq delays etc). If there are, the behavior depends on
+ * whether URB_ISO_ASAP is set.
*/
if (likely (!list_empty (&stream->td_list))) {
- u32 excess;
- /* For high speed devices, allow scheduling within the
- * isochronous scheduling threshold. For full speed devices
- * and Intel PCI-based controllers, don't (work around for
- * Intel ICH9 bug).
- */
- if (!stream->highspeed && ehci->fs_i_thresh)
- next = now + ehci->i_thresh;
+ /* Take the isochronous scheduling threshold into account */
+ if (ehci->i_thresh)
+ next = now + ehci->i_thresh; /* uframe cache */
else
- next = now;
+ next = (now + 2 + 7) & ~0x07; /* full frame cache */
- /* Fell behind (by up to twice the slop amount)?
- * We decide based on the time of the last currently-scheduled
- * slot, not the time of the next available slot.
+ /*
+ * Use ehci->last_iso_frame as the base. There can't be any
+ * TDs scheduled for earlier than that.
*/
- excess = (stream->next_uframe - period - next) & (mod - 1);
- if (excess >= mod - 2 * SCHEDULE_SLOP)
- start = next + excess - mod + period *
- DIV_ROUND_UP(mod - excess, period);
- else
- start = next + excess + period;
- if (start - now >= mod) {
- ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
- urb, start - now - period, period,
- mod);
- status = -EFBIG;
+ base = ehci->last_iso_frame << 3;
+ next = (next - base) & (mod - 1);
+ start = (stream->next_uframe - base) & (mod - 1);
+
+ /* Is the schedule already full? */
+ if (unlikely(start < period)) {
+ ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n",
+ urb, stream->next_uframe, base,
+ period, mod);
+ status = -ENOSPC;
goto fail;
}
+
+ /* Behind the scheduling threshold? */
+ if (unlikely(start < next)) {
+
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ start += (next - start + period - 1) & -period;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
+ */
+ else if (start + span - period < next) {
+ ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n",
+ urb, start + base,
+ span - period, next + base);
+ status = -EXDEV;
+ goto fail;
+ }
+ }
+
+ start += base;
}
/* need to schedule; when's the next (u)frame we could start?
* this is bigger than ehci->i_thresh allows; scheduling itself
- * isn't free, the slop should handle reasonably slow cpus. it
+ * isn't free, the delay should handle reasonably slow cpus. it
* can also help high bandwidth if the dma and irq loads don't
* jump until after the queue is primed.
*/
else {
int done = 0;
- start = SCHEDULE_SLOP + (now & ~0x07);
- /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
+ base = now & ~0x07;
+ start = base + SCHEDULING_DELAY;
/* find a uframe slot with enough bandwidth.
* Early uframes are more precious because full-speed
@@ -1464,19 +1451,16 @@ iso_stream_schedule (
/* no room in the schedule */
if (!done) {
- ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
- urb, now, now + mod);
+ ehci_dbg(ehci, "iso sched full %p", urb);
status = -ENOSPC;
goto fail;
}
}
/* Tried to schedule too far into the future? */
- if (unlikely(start - now + span - period
- >= mod - 2 * SCHEDULE_SLOP)) {
- ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
- urb, start - now, span - period,
- mod - 2 * SCHEDULE_SLOP);
+ if (unlikely(start - base + span - period >= mod)) {
+ ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n",
+ urb, start - base, span - period, mod);
status = -EFBIG;
goto fail;
}
@@ -1490,7 +1474,7 @@ iso_stream_schedule (
/* Make sure scan_isoc() sees these */
if (ehci->isoc_count == 0)
- ehci->next_frame = now >> 3;
+ ehci->last_iso_frame = now >> 3;
return 0;
fail:
@@ -1646,7 +1630,7 @@ static void itd_link_urb(
/* don't need that schedule data any more */
iso_sched_free (stream, iso_sched);
- urb->hcpriv = NULL;
+ urb->hcpriv = stream;
++ehci->isoc_count;
enable_periodic(ehci);
@@ -1708,7 +1692,7 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd)
urb->actual_length += desc->actual_length;
} else {
/* URB was too late */
- desc->status = -EXDEV;
+ urb->error_count++;
}
}
@@ -2045,7 +2029,7 @@ static void sitd_link_urb(
/* don't need that schedule data any more */
iso_sched_free (stream, sched);
- urb->hcpriv = NULL;
+ urb->hcpriv = stream;
++ehci->isoc_count;
enable_periodic(ehci);
@@ -2081,7 +2065,7 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd)
t = hc32_to_cpup(ehci, &sitd->hw_results);
/* report transfer status */
- if (t & SITD_ERRS) {
+ if (unlikely(t & SITD_ERRS)) {
urb->error_count++;
if (t & SITD_STS_DBE)
desc->status = usb_pipein (urb->pipe)
@@ -2091,6 +2075,9 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd)
desc->status = -EOVERFLOW;
else /* XACT, MMF, etc */
desc->status = -EPROTO;
+ } else if (unlikely(t & SITD_STS_ACTIVE)) {
+ /* URB was too late */
+ urb->error_count++;
} else {
desc->status = 0;
desc->actual_length = desc->length - SITD_LENGTH(t);
@@ -2220,16 +2207,16 @@ static void scan_isoc(struct ehci_hcd *ehci)
now_frame = (uf >> 3) & fmask;
live = true;
} else {
- now_frame = (ehci->next_frame - 1) & fmask;
+ now_frame = (ehci->last_iso_frame - 1) & fmask;
live = false;
}
ehci->now_frame = now_frame;
- frame = ehci->next_frame;
for (;;) {
union ehci_shadow q, *q_p;
__hc32 type, *hw_p;
+ frame = ehci->last_iso_frame;
restart:
/* scan each element in frame's queue for completions */
q_p = &ehci->pshadow [frame];
@@ -2334,7 +2321,6 @@ restart:
/* Stop when we have reached the current frame */
if (frame == now_frame)
break;
- frame = (frame + 1) & fmask;
+ ehci->last_iso_frame = (frame + 1) & fmask;
}
- ehci->next_frame = now_frame;
}
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c
index 6081e1ed3ac..0c90a24fa98 100644
--- a/drivers/usb/host/ehci-sh.c
+++ b/drivers/usb/host/ehci-sh.c
@@ -21,17 +21,10 @@ struct ehci_sh_priv {
static int ehci_sh_reset(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
ehci->caps = hcd->regs;
- ret = ehci_setup(hcd);
- if (unlikely(ret))
- return ret;
-
- ehci_port_power(ehci, 0);
-
- return ret;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_sh_hc_driver = {
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
index c718a065e15..466c1bb5b96 100644
--- a/drivers/usb/host/ehci-spear.c
+++ b/drivers/usb/host/ehci-spear.c
@@ -37,18 +37,11 @@ static void spear_stop_ehci(struct spear_ehci *ehci)
static int ehci_spear_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval = 0;
/* registers start at offset 0x0 */
ehci->caps = hcd->regs;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_spear_hc_driver = {
@@ -116,8 +109,6 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
struct clk *usbh_clk;
const struct hc_driver *driver = &ehci_spear_hc_driver;
int irq, retval;
- char clk_name[20] = "usbh_clk";
- static int instance = -1;
if (usb_disabled())
return -ENODEV;
@@ -125,7 +116,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
retval = irq;
- goto fail_irq_get;
+ goto fail;
}
/*
@@ -136,47 +127,38 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &spear_ehci_dma_mask;
- /*
- * Increment the device instance, when probing via device-tree
- */
- if (pdev->id < 0)
- instance++;
- else
- instance = pdev->id;
- sprintf(clk_name, "usbh.%01d_clk", instance);
-
- usbh_clk = clk_get(NULL, clk_name);
+ usbh_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(usbh_clk)) {
dev_err(&pdev->dev, "Error getting interface clock\n");
retval = PTR_ERR(usbh_clk);
- goto fail_get_usbh_clk;
+ goto fail;
}
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
retval = -ENOMEM;
- goto fail_create_hcd;
+ goto fail;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
retval = -ENODEV;
- goto fail_request_resource;
+ goto err_put_hcd;
}
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+ if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
retval = -EBUSY;
- goto fail_request_resource;
+ goto err_put_hcd;
}
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
if (hcd->regs == NULL) {
dev_dbg(&pdev->dev, "error mapping memory\n");
retval = -ENOMEM;
- goto fail_ioremap;
+ goto err_put_hcd;
}
ehci = (struct spear_ehci *)hcd_to_ehci(hcd);
@@ -185,21 +167,15 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
spear_start_ehci(ehci);
retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (retval)
- goto fail_add_hcd;
+ goto err_stop_ehci;
return retval;
-fail_add_hcd:
+err_stop_ehci:
spear_stop_ehci(ehci);
- iounmap(hcd->regs);
-fail_ioremap:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-fail_request_resource:
+err_put_hcd:
usb_put_hcd(hcd);
-fail_create_hcd:
- clk_put(usbh_clk);
-fail_get_usbh_clk:
-fail_irq_get:
+fail:
dev_err(&pdev->dev, "init fail, %d\n", retval);
return retval ;
@@ -218,17 +194,12 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
if (ehci_p->clk)
spear_stop_ehci(ehci_p);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
- if (ehci_p->clk)
- clk_put(ehci_p->clk);
-
return 0;
}
-static struct of_device_id spear_ehci_id_table[] __devinitdata = {
+static struct of_device_id spear_ehci_id_table[] = {
{ .compatible = "st,spear600-ehci", },
{ },
};
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 6223d175784..acf17556bd8 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -28,7 +28,10 @@
#include <linux/pm_runtime.h>
#include <linux/usb/tegra_usb_phy.h>
-#include <mach/iomap.h>
+
+#define TEGRA_USB_BASE 0xC5000000
+#define TEGRA_USB2_BASE 0xC5004000
+#define TEGRA_USB3_BASE 0xC5008000
#define TEGRA_USB_DMA_ALIGN 32
@@ -277,7 +280,6 @@ static void tegra_ehci_shutdown(struct usb_hcd *hcd)
static int tegra_ehci_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
@@ -285,12 +287,7 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)
/* switch to host mode */
hcd->has_tt = 1;
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 1);
- return retval;
+ return ehci_setup(hcd);
}
struct dma_aligned_buffer {
@@ -778,9 +775,6 @@ static int tegra_ehci_remove(struct platform_device *pdev)
struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev);
struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci);
- if (tegra == NULL || hcd == NULL)
- return -EINVAL;
-
pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
@@ -811,7 +805,7 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev)
hcd->driver->shutdown(hcd);
}
-static struct of_device_id tegra_ehci_of_match[] __devinitdata = {
+static struct of_device_id tegra_ehci_of_match[] = {
{ .compatible = "nvidia,tegra20-ehci", },
{ },
};
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
index d3c9a3e397b..11695d5b9d8 100644
--- a/drivers/usb/host/ehci-vt8500.c
+++ b/drivers/usb/host/ehci-vt8500.c
@@ -19,22 +19,6 @@
#include <linux/of.h>
#include <linux/platform_device.h>
-static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int rc = 0;
-
- if (!udev->parent) /* udev is root hub itself, impossible */
- rc = -1;
- /* we only support lpm device connected to root hub yet */
- if (ehci->has_lpm && !udev->parent->parent) {
- rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
- if (!rc)
- rc = ehci_lpm_check(ehci, udev->portnum);
- }
- return rc;
-}
-
static const struct hc_driver vt8500_ehci_hc_driver = {
.description = hcd_name,
.product_desc = "VT8500 EHCI",
@@ -77,11 +61,6 @@ static const struct hc_driver vt8500_ehci_hc_driver = {
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
- /*
- * call back when device connected and addressed
- */
- .update_device = ehci_update_device,
-
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c
index ec598082c14..59e0e24c753 100644
--- a/drivers/usb/host/ehci-w90x900.c
+++ b/drivers/usb/host/ehci-w90x900.c
@@ -13,12 +13,12 @@
#include <linux/platform_device.h>
-/*ebable phy0 and phy1 for w90p910*/
+/* enable phy0 and phy1 for w90p910 */
#define ENPHY (0x01<<8)
#define PHY0_CTR (0xA4)
#define PHY1_CTR (0xA8)
-static int __devinit usb_w90x900_probe(const struct hc_driver *driver,
+static int usb_w90x900_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
struct usb_hcd *hcd;
@@ -147,7 +147,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static int __devinit ehci_w90x900_probe(struct platform_device *pdev)
+static int ehci_w90x900_probe(struct platform_device *pdev)
{
if (usb_disabled())
return -ENODEV;
@@ -155,7 +155,7 @@ static int __devinit ehci_w90x900_probe(struct platform_device *pdev)
return usb_w90x900_probe(&ehci_w90x900_hc_driver, pdev);
}
-static int __devexit ehci_w90x900_remove(struct platform_device *pdev)
+static int ehci_w90x900_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -166,7 +166,7 @@ static int __devexit ehci_w90x900_remove(struct platform_device *pdev)
static struct platform_driver ehci_hcd_w90x900_driver = {
.probe = ehci_w90x900_probe,
- .remove = __devexit_p(ehci_w90x900_remove),
+ .remove = ehci_w90x900_remove,
.driver = {
.name = "w90x900-ehci",
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
index 6a3f921a5d7..4f285e8e404 100644
--- a/drivers/usb/host/ehci-xilinx-of.c
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -125,7 +125,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
* as HS only or HS/FS only, it checks the configuration in the device tree
* entry, and sets an appropriate value for hcd->has_tt.
*/
-static int __devinit ehci_hcd_xilinx_of_probe(struct platform_device *op)
+static int ehci_hcd_xilinx_of_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c
deleted file mode 100644
index 8dc6a22d90b..00000000000
--- a/drivers/usb/host/ehci-xls.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * EHCI HCD for Netlogic XLS processors.
- *
- * (C) Copyright 2011 Netlogic Microsystems Inc.
- *
- * Based on various ehci-*.c drivers
- *
- * 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.
- */
-
-#include <linux/platform_device.h>
-
-static int ehci_xls_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-
- ehci->caps = hcd->regs;
-
- return ehci_setup(hcd);
-}
-
-int ehci_xls_probe_internal(const struct hc_driver *driver,
- struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int retval, irq;
-
- /* Get our IRQ from an earlier registered Platform Resource */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
-
- /* Get our Memory Handle */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Error: MMIO Handle %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd) {
- retval = -ENOMEM;
- goto err1;
- }
-
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(&pdev->dev, "controller already in use\n");
- retval = -EBUSY;
- goto err2;
- }
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
-
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err3;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval != 0)
- goto err4;
- return retval;
-
-err4:
- iounmap(hcd->regs);
-err3:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err2:
- usb_put_hcd(hcd);
-err1:
- dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev),
- retval);
- return retval;
-}
-
-static struct hc_driver ehci_xls_hc_driver = {
- .description = hcd_name,
- .product_desc = "XLS EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_USB2 | HCD_MEMORY,
- .reset = ehci_xls_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- .get_frame_number = ehci_get_frame,
-
- .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 int ehci_xls_probe(struct platform_device *pdev)
-{
- if (usb_disabled())
- return -ENODEV;
-
- return ehci_xls_probe_internal(&ehci_xls_hc_driver, pdev);
-}
-
-static int ehci_xls_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- return 0;
-}
-
-MODULE_ALIAS("ehci-xls");
-
-static struct platform_driver ehci_xls_driver = {
- .probe = ehci_xls_probe,
- .remove = ehci_xls_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ehci-xls",
- },
-};
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index da07d98f7d1..36c3a821059 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -38,6 +38,10 @@ typedef __u16 __bitwise __hc16;
#endif
/* statistics can be kept for tuning/monitoring */
+#ifdef DEBUG
+#define EHCI_STATS
+#endif
+
struct ehci_stats {
/* irq usage */
unsigned long normal;
@@ -143,7 +147,7 @@ struct ehci_hcd { /* one per controller */
struct ehci_qh *intr_unlink_last;
unsigned intr_unlink_cycle;
unsigned now_frame; /* frame from HC hardware */
- unsigned next_frame; /* scan periodic, start here */
+ unsigned last_iso_frame; /* last frame scanned for iso */
unsigned intr_count; /* intr activity count */
unsigned isoc_count; /* isoc activity count */
unsigned periodic_count; /* periodic activity count */
@@ -193,7 +197,6 @@ struct ehci_hcd { /* one per controller */
unsigned has_amcc_usb23:1;
unsigned need_io_watchdog:1;
unsigned amd_pll_fix:1;
- unsigned fs_i_thresh:1; /* Intel iso scheduling */
unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
@@ -207,7 +210,6 @@ struct ehci_hcd { /* one per controller */
#define OHCI_HCCTRL_LEN 0x4
__hc32 *ohci_hcctrl_reg;
unsigned has_hostpc:1;
- unsigned has_lpm:1; /* support link power management */
unsigned has_ppcd:1; /* support per-port change bits */
u8 sbrn; /* packed release number */
@@ -223,6 +225,9 @@ struct ehci_hcd { /* one per controller */
#ifdef DEBUG
struct dentry *debug_dir;
#endif
+
+ /* platform-specific data -- must come last */
+ unsigned long priv[0] __aligned(sizeof(s64));
};
/* convert between an HCD pointer and the corresponding EHCI_HCD */
@@ -762,26 +767,41 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_PCI
-
-/* For working around the MosChip frame-index-register bug */
-static unsigned ehci_read_frame_index(struct ehci_hcd *ehci);
-
+#define ehci_dbg(ehci, fmt, args...) \
+ dev_dbg(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+#define ehci_err(ehci, fmt, args...) \
+ dev_err(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+#define ehci_info(ehci, fmt, args...) \
+ dev_info(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+#define ehci_warn(ehci, fmt, args...) \
+ dev_warn(ehci_to_hcd(ehci)->self.controller , fmt , ## args)
+
+#ifdef VERBOSE_DEBUG
+# define ehci_vdbg ehci_dbg
#else
-
-static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
-{
- return ehci_readl(ehci, &ehci->regs->frame_index);
-}
-
+ static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {}
#endif
-/*-------------------------------------------------------------------------*/
-
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
/*-------------------------------------------------------------------------*/
+/* Declarations of things exported for use by ehci platform drivers */
+
+struct ehci_driver_overrides {
+ size_t extra_priv_size;
+ int (*reset)(struct usb_hcd *hcd);
+};
+
+extern void ehci_init_driver(struct hc_driver *drv,
+ const struct ehci_driver_overrides *over);
+extern int ehci_setup(struct usb_hcd *hcd);
+
+#ifdef CONFIG_PM
+extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup);
+extern int ehci_resume(struct usb_hcd *hcd, bool hibernated);
+#endif /* CONFIG_PM */
+
#endif /* __LINUX_EHCI_HCD_H */
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index 7da1a26bed2..0b46542591f 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -561,7 +561,7 @@ static const struct hc_driver fhci_driver = {
.hub_control = fhci_hub_control,
};
-static int __devinit of_fhci_probe(struct platform_device *ofdev)
+static int of_fhci_probe(struct platform_device *ofdev)
{
struct device *dev = &ofdev->dev;
struct device_node *node = dev->of_node;
@@ -780,7 +780,7 @@ err_regs:
return ret;
}
-static int __devexit fhci_remove(struct device *dev)
+static int fhci_remove(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct fhci_hcd *fhci = hcd_to_fhci(hcd);
@@ -803,7 +803,7 @@ static int __devexit fhci_remove(struct device *dev)
return 0;
}
-static int __devexit of_fhci_remove(struct platform_device *ofdev)
+static int of_fhci_remove(struct platform_device *ofdev)
{
return fhci_remove(&ofdev->dev);
}
@@ -821,7 +821,7 @@ static struct platform_driver of_fhci_driver = {
.of_match_table = of_fhci_match,
},
.probe = of_fhci_probe,
- .remove = __devexit_p(of_fhci_remove),
+ .remove = of_fhci_remove,
};
module_platform_driver(of_fhci_driver);
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 1e771292383..11e0b79ff9d 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -24,7 +24,7 @@ struct fsl_usb2_dev_data {
enum fsl_usb2_operating_modes op_mode; /* operating mode */
};
-struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = {
+struct fsl_usb2_dev_data dr_mode_data[] = {
{
.dr_mode = "host",
.drivers = { "fsl-ehci", NULL, NULL, },
@@ -42,7 +42,7 @@ struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = {
},
};
-struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np)
+struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np)
{
const unsigned char *prop;
int i;
@@ -59,7 +59,7 @@ struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np)
return &dr_mode_data[0]; /* mode not specified, use host */
}
-static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type)
+static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
{
if (!phy_type)
return FSL_USB2_PHY_NONE;
@@ -75,7 +75,7 @@ static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type)
return FSL_USB2_PHY_NONE;
}
-struct platform_device * __devinit fsl_usb2_device_register(
+struct platform_device *fsl_usb2_device_register(
struct platform_device *ofdev,
struct fsl_usb2_platform_data *pdata,
const char *name, int id)
@@ -142,6 +142,9 @@ static int usb_get_ver_info(struct device_node *np)
return ver;
}
+ if (of_device_is_compatible(np, "fsl,mpc5121-usb2-dr"))
+ return FSL_USB_VER_OLD;
+
if (of_device_is_compatible(np, "fsl-usb2-mph")) {
if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6"))
ver = FSL_USB_VER_1_6;
@@ -154,7 +157,7 @@ static int usb_get_ver_info(struct device_node *np)
return ver;
}
-static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
+static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct platform_device *usb_dev;
@@ -224,13 +227,13 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
return 0;
}
-static int __devexit __unregister_subdev(struct device *dev, void *d)
+static int __unregister_subdev(struct device *dev, void *d)
{
platform_device_unregister(to_platform_device(dev));
return 0;
}
-static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
+static int fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
{
device_for_each_child(&ofdev->dev, NULL, __unregister_subdev);
return 0;
@@ -336,7 +339,7 @@ static struct platform_driver fsl_usb2_mph_dr_driver = {
.of_match_table = fsl_usb2_mph_dr_of_match,
},
.probe = fsl_usb2_mph_dr_of_probe,
- .remove = __devexit_p(fsl_usb2_mph_dr_of_remove),
+ .remove = fsl_usb2_mph_dr_of_remove,
};
module_platform_driver(fsl_usb2_mph_dr_driver);
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index f19e2690c23..f0ebe8e7c58 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -58,6 +58,7 @@
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/dma-mapping.h>
+#include <linux/module.h>
#include "imx21-hcd.h"
@@ -1680,7 +1681,7 @@ static int imx21_hc_reset(struct usb_hcd *hcd)
return 0;
}
-static int __devinit imx21_hc_start(struct usb_hcd *hcd)
+static int imx21_hc_start(struct usb_hcd *hcd)
{
struct imx21 *imx21 = hcd_to_imx21(hcd);
unsigned long flags;
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 9e65e3091c8..b64e661618b 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1557,7 +1557,7 @@ static int isp116x_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit isp116x_probe(struct platform_device *pdev)
+static int isp116x_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct isp116x *isp116x;
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 256326322cf..974480c516f 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2645,7 +2645,7 @@ static struct hc_driver isp1362_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int __devexit isp1362_remove(struct platform_device *pdev)
+static int isp1362_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd);
@@ -2680,7 +2680,7 @@ static int __devexit isp1362_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit isp1362_probe(struct platform_device *pdev)
+static int isp1362_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct isp1362_hcd *isp1362_hcd;
@@ -2856,7 +2856,7 @@ static int isp1362_resume(struct platform_device *pdev)
static struct platform_driver isp1362_driver = {
.probe = isp1362_probe,
- .remove = __devexit_p(isp1362_remove),
+ .remove = isp1362_remove,
.suspend = isp1362_suspend,
.resume = isp1362_resume,
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index fff114fd546..bbb791bd761 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -43,7 +43,6 @@ static int of_isp1760_probe(struct platform_device *dev)
struct device_node *dp = dev->dev.of_node;
struct resource *res;
struct resource memory;
- struct of_irq oirq;
int virq;
resource_size_t res_len;
int ret;
@@ -69,14 +68,12 @@ static int of_isp1760_probe(struct platform_device *dev)
goto free_data;
}
- if (of_irq_map_one(dp, 0, &oirq)) {
+ virq = irq_of_parse_and_map(dp, 0);
+ if (!virq) {
ret = -ENODEV;
goto release_reg;
}
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
-
if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
devflags |= ISP1760_FLAG_ISP1761;
@@ -175,7 +172,7 @@ static struct platform_driver isp1760_of_driver = {
#endif
#ifdef CONFIG_PCI
-static int __devinit isp1761_pci_probe(struct pci_dev *dev,
+static int isp1761_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
u8 latency, limit;
@@ -349,7 +346,7 @@ static struct pci_driver isp1761_pci_driver = {
};
#endif
-static int __devinit isp1760_plat_probe(struct platform_device *pdev)
+static int isp1760_plat_probe(struct platform_device *pdev)
{
int ret = 0;
struct usb_hcd *hcd;
@@ -416,7 +413,7 @@ out:
return ret;
}
-static int __devexit isp1760_plat_remove(struct platform_device *pdev)
+static int isp1760_plat_remove(struct platform_device *pdev)
{
struct resource *mem_res;
resource_size_t mem_size;
@@ -435,7 +432,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
static struct platform_driver isp1760_plat_driver = {
.probe = isp1760_plat_probe,
- .remove = __devexit_p(isp1760_plat_remove),
+ .remove = isp1760_plat_remove,
.driver = {
.name = "isp1760",
},
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 0bf72f943b0..a0cb44f0e72 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -16,11 +16,11 @@
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
+#include <linux/platform_data/atmel.h>
#include <mach/hardware.h>
#include <asm/gpio.h>
-#include <mach/board.h>
#include <mach/cpu.h>
#ifndef CONFIG_ARCH_AT91
@@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -108,7 +108,7 @@ static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_dev
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
-static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
+static int usb_hcd_at91_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
int retval;
@@ -203,7 +203,7 @@ static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
* context, "rmmod" or something similar.
*
*/
-static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void usb_hcd_at91_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
usb_remove_hcd(hcd);
@@ -222,7 +222,7 @@ static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
/*-------------------------------------------------------------------------*/
-static int __devinit
+static int
ohci_at91_reset (struct usb_hcd *hcd)
{
struct at91_usbh_data *board = hcd->self.controller->platform_data;
@@ -236,7 +236,7 @@ ohci_at91_reset (struct usb_hcd *hcd)
return 0;
}
-static int __devinit
+static int
ohci_at91_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@@ -506,7 +506,7 @@ MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit ohci_at91_of_init(struct platform_device *pdev)
+static int ohci_at91_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
int i, gpio;
@@ -548,7 +548,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
return 0;
}
#else
-static int __devinit ohci_at91_of_init(struct platform_device *pdev)
+static int ohci_at91_of_init(struct platform_device *pdev)
{
return 0;
}
@@ -556,7 +556,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{
struct at91_usbh_data *pdata;
int i;
@@ -641,7 +641,7 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
}
-static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
{
struct at91_usbh_data *pdata = pdev->dev.platform_data;
int i;
@@ -705,7 +705,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
if (!clocked)
at91_start_clock();
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#else
@@ -717,7 +717,7 @@ MODULE_ALIAS("platform:at91_ohci");
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
- .remove = __devexit_p(ohci_hcd_at91_drv_remove),
+ .remove = ohci_hcd_at91_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.suspend = ohci_hcd_at91_drv_suspend,
.resume = ohci_hcd_at91_drv_resume,
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
deleted file mode 100644
index c611699b4aa..00000000000
--- a/drivers/usb/host/ohci-au1xxx.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Copyright 2002 Hewlett-Packard Company
- *
- * Bus Glue for AMD Alchemy Au1xxx
- *
- * Written by Christopher Hoover <ch@hpl.hp.com>
- * Based on fragments of previous driver by Russell King et al.
- *
- * Modified for LH7A404 from ohci-sa1111.c
- * by Durgesh Pattamatta <pattamattad@sharpsec.com>
- * Modified for AMD Alchemy Au1xxx
- * by Matt Porter <mporter@kernel.crashing.org>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-#include <asm/mach-au1x00/au1000.h>
-
-
-extern int usb_disabled(void);
-
-static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- ohci_dbg(ohci, "ohci_au1xxx_start, ohci:%p", ohci);
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run(ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
-
- return 0;
-}
-
-static const struct hc_driver ohci_au1xxx_hc_driver = {
- .description = hcd_name,
- .product_desc = "Au1xxx OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_au1xxx_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,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
-{
- int ret, unit;
- struct usb_hcd *hcd;
-
- if (usb_disabled())
- return -ENODEV;
-
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ\n");
- return -ENOMEM;
- }
-
- hcd = usb_create_hcd(&ohci_au1xxx_hc_driver, &pdev->dev, "au1xxx");
- if (!hcd)
- return -ENOMEM;
-
- hcd->rsrc_start = pdev->resource[0].start;
- hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_debug("request_mem_region failed\n");
- ret = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- pr_debug("ioremap failed\n");
- ret = -ENOMEM;
- goto err2;
- }
-
- unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
- ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
- if (alchemy_usb_control(unit, 1)) {
- printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
- ret = -ENODEV;
- goto err3;
- }
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- ret = usb_add_hcd(hcd, pdev->resource[1].start,
- IRQF_SHARED);
- if (ret == 0) {
- platform_set_drvdata(pdev, hcd);
- return ret;
- }
-
- alchemy_usb_control(unit, 0);
-err3:
- iounmap(hcd->regs);
-err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
- int unit;
-
- unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
- ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
- usb_remove_hcd(hcd);
- alchemy_usb_control(unit, 0);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- unsigned long flags;
- int rc;
-
- rc = 0;
-
- /* Root hub was already suspended. Disable irq emission and
- * mark HW unaccessible, bail out if RH has been resumed. Use
- * the spinlock to properly synchronize with possible pending
- * RH suspend or resume activity.
- */
- spin_lock_irqsave(&ohci->lock, flags);
- if (ohci->rh_state != OHCI_RH_SUSPENDED) {
- rc = -EINVAL;
- goto bail;
- }
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
- (void)ohci_readl(ohci, &ohci->regs->intrdisable);
-
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
-bail:
- spin_unlock_irqrestore(&ohci->lock, flags);
-
- return rc;
-}
-
-static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
-
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 1);
-
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- ohci_finish_controller_resume(hcd);
-
- return 0;
-}
-
-static const struct dev_pm_ops au1xxx_ohci_pmops = {
- .suspend = ohci_hcd_au1xxx_drv_suspend,
- .resume = ohci_hcd_au1xxx_drv_resume,
-};
-
-#define AU1XXX_OHCI_PMOPS &au1xxx_ohci_pmops
-
-#else
-#define AU1XXX_OHCI_PMOPS NULL
-#endif
-
-static struct platform_driver ohci_hcd_au1xxx_driver = {
- .probe = ohci_hcd_au1xxx_drv_probe,
- .remove = ohci_hcd_au1xxx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "au1xxx-ohci",
- .owner = THIS_MODULE,
- .pm = AU1XXX_OHCI_PMOPS,
- },
-};
-
-MODULE_ALIAS("platform:au1xxx-ohci");
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c
deleted file mode 100644
index 2c9f233047b..00000000000
--- a/drivers/usb/host/ohci-cns3xxx.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2008 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/atomic.h>
-#include <mach/cns3xxx.h>
-#include <mach/pm.h>
-
-static int __devinit
-cns3xxx_ohci_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- *
- * Set USB AHB INCR length to 16
- */
- if (atomic_inc_return(&usb_pwr_ref) == 1) {
- cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
- cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
- cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
- __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
- MISC_CHIP_CONFIG_REG);
- }
-
- ret = ohci_init(ohci);
- if (ret < 0)
- return ret;
-
- ohci->num_ports = 1;
-
- ret = ohci_run(ohci);
- if (ret < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
- return 0;
-}
-
-static const struct hc_driver cns3xxx_ohci_hc_driver = {
- .description = hcd_name,
- .product_desc = "CNS3XXX OHCI Host controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
- .start = cns3xxx_ohci_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
- .get_frame_number = ohci_get_frame,
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int cns3xxx_ohci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &cns3xxx_ohci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "Found HC with no IRQ.\n");
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, dev, dev_name(dev));
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "Found HC with no register addr.\n");
- retval = -ENODEV;
- goto err1;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(dev, "controller already in use\n");
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_dbg(dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err2;
- }
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval == 0)
- return retval;
-
- iounmap(hcd->regs);
-err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-static int cns3xxx_ohci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- */
- if (atomic_dec_return(&usb_pwr_ref) == 0)
- cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
-
- usb_put_hcd(hcd);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:cns3xxx-ohci");
-
-static struct platform_driver ohci_hcd_cns3xxx_driver = {
- .probe = cns3xxx_ohci_probe,
- .remove = cns3xxx_ohci_remove,
- .driver = {
- .name = "cns3xxx-ohci",
- },
-};
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index dbfbd1dfd2e..8704e9fa5a8 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -107,7 +107,7 @@ static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd,
usb_put_hcd(hcd);
}
-static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd)
+static int ohci_ep93xx_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
@@ -194,7 +194,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
ep93xx_start_hc(&pdev->dev);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#endif
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 20a50081f92..aa3b8844bb9 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -23,6 +23,11 @@ struct exynos_ohci_hcd {
struct clk *clk;
};
+static int ohci_exynos_reset(struct usb_hcd *hcd)
+{
+ return ohci_init(hcd_to_ohci(hcd));
+}
+
static int ohci_exynos_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
@@ -30,10 +35,6 @@ static int ohci_exynos_start(struct usb_hcd *hcd)
ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
- ret = ohci_init(ohci);
- if (ret < 0)
- return ret;
-
ret = ohci_run(ohci);
if (ret < 0) {
dev_err(hcd->self.controller, "can't start %s\n",
@@ -53,6 +54,7 @@ static const struct hc_driver exynos_ohci_hc_driver = {
.irq = ohci_irq,
.flags = HCD_MEMORY|HCD_USB11,
+ .reset = ohci_exynos_reset,
.start = ohci_exynos_start,
.stop = ohci_stop,
.shutdown = ohci_shutdown,
@@ -74,7 +76,7 @@ static const struct hc_driver exynos_ohci_hc_driver = {
static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
-static int __devinit exynos_ohci_probe(struct platform_device *pdev)
+static int exynos_ohci_probe(struct platform_device *pdev)
{
struct exynos4_ohci_platdata *pdata;
struct exynos_ohci_hcd *exynos_ohci;
@@ -115,7 +117,7 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev)
}
exynos_ohci->hcd = hcd;
- exynos_ohci->clk = clk_get(&pdev->dev, "usbhost");
+ exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
if (IS_ERR(exynos_ohci->clk)) {
dev_err(&pdev->dev, "Failed to get usbhost clock\n");
@@ -123,9 +125,9 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev)
goto fail_clk;
}
- err = clk_enable(exynos_ohci->clk);
+ err = clk_prepare_enable(exynos_ohci->clk);
if (err)
- goto fail_clken;
+ goto fail_clk;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -167,15 +169,13 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev)
return 0;
fail_io:
- clk_disable(exynos_ohci->clk);
-fail_clken:
- clk_put(exynos_ohci->clk);
+ clk_disable_unprepare(exynos_ohci->clk);
fail_clk:
usb_put_hcd(hcd);
return err;
}
-static int __devexit exynos_ohci_remove(struct platform_device *pdev)
+static int exynos_ohci_remove(struct platform_device *pdev)
{
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
@@ -186,8 +186,7 @@ static int __devexit exynos_ohci_remove(struct platform_device *pdev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(exynos_ohci->clk);
- clk_put(exynos_ohci->clk);
+ clk_disable_unprepare(exynos_ohci->clk);
usb_put_hcd(hcd);
@@ -232,7 +231,7 @@ static int exynos_ohci_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
- clk_disable(exynos_ohci->clk);
+ clk_disable_unprepare(exynos_ohci->clk);
fail:
spin_unlock_irqrestore(&ohci->lock, flags);
@@ -247,15 +246,12 @@ static int exynos_ohci_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
- clk_enable(exynos_ohci->clk);
+ clk_prepare_enable(exynos_ohci->clk);
if (pdata && pdata->phy_init)
pdata->phy_init(pdev, S5P_USB_PHY_HOST);
- /* Mark hardware accessible again as we are out of D3 state by now */
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -279,7 +275,7 @@ MODULE_DEVICE_TABLE(of, exynos_ohci_match);
static struct platform_driver exynos_ohci_driver = {
.probe = exynos_ohci_probe,
- .remove = __devexit_p(exynos_ohci_remove),
+ .remove = exynos_ohci_remove,
.shutdown = exynos_ohci_shutdown,
.driver = {
.name = "exynos-ohci",
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 4a1d64d9233..180a2b01db5 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -231,13 +231,41 @@ static int ohci_urb_enqueue (
frame &= ~(ed->interval - 1);
frame |= ed->branch;
urb->start_frame = frame;
+ }
+ } else if (ed->type == PIPE_ISOCHRONOUS) {
+ u16 next = ohci_frame_no(ohci) + 2;
+ u16 frame = ed->last_iso + ed->interval;
+
+ /* Behind the scheduling threshold? */
+ if (unlikely(tick_before(frame, next))) {
- /* yes, only URB_ISO_ASAP is supported, and
- * urb->start_frame is never used as input.
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ frame += (next - frame + ed->interval - 1) &
+ -ed->interval;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
*/
+ else if (tick_before(frame + ed->interval *
+ (urb->number_of_packets - 1), next)) {
+ retval = -EXDEV;
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ goto fail;
+ }
+
+ /*
+ * Some OHCI hardware doesn't handle late TDs
+ * correctly. After retiring them it proceeds to
+ * the next ED instead of the next TD. Therefore
+ * we have to omit the late TDs entirely.
+ */
+ urb_priv->td_cnt = DIV_ROUND_UP(next - frame,
+ ed->interval);
}
- } else if (ed->type == PIPE_ISOCHRONOUS)
- urb->start_frame = ed->last_iso + ed->interval;
+ urb->start_frame = frame;
+ }
/* fill the TDs and link them to the ed; and
* enable that part of the schedule, if needed
@@ -983,6 +1011,79 @@ static int ohci_restart (struct ohci_hcd *ohci)
#endif
+#ifdef CONFIG_PM
+
+static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ unsigned long flags;
+
+ /* Disable irq emission and mark HW unaccessible. Use
+ * the spinlock to properly synchronize with possible pending
+ * RH suspend or resume activity.
+ */
+ spin_lock_irqsave (&ohci->lock, flags);
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ (void)ohci_readl(ohci, &ohci->regs->intrdisable);
+
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ spin_unlock_irqrestore (&ohci->lock, flags);
+
+ return 0;
+}
+
+
+static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int port;
+ bool need_reinit = false;
+
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+ /* Make sure resume from hibernation re-enumerates everything */
+ if (hibernated)
+ ohci_usb_reset(ohci);
+
+ /* See if the controller is already running or has been reset */
+ ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+ if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
+ need_reinit = true;
+ } else {
+ switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+ case OHCI_USB_OPER:
+ case OHCI_USB_RESET:
+ need_reinit = true;
+ }
+ }
+
+ /* If needed, reinitialize and suspend the root hub */
+ if (need_reinit) {
+ spin_lock_irq(&ohci->lock);
+ ohci_rh_resume(ohci);
+ ohci_rh_suspend(ohci, 0);
+ spin_unlock_irq(&ohci->lock);
+ }
+
+ /* Normally just turn on port power and enable interrupts */
+ else {
+ ohci_dbg(ohci, "powerup ports\n");
+ for (port = 0; port < ohci->num_ports; port++)
+ ohci_writel(ohci, RH_PS_PPS,
+ &ohci->regs->roothub.portstatus[port]);
+
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
+ ohci_readl(ohci, &ohci->regs->intrenable);
+ msleep(20);
+ }
+
+ usb_hcd_resume_root_hub(hcd);
+
+ return 0;
+}
+
+#endif
+
/*-------------------------------------------------------------------------*/
MODULE_AUTHOR (DRIVER_AUTHOR);
@@ -1029,21 +1130,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_ep93xx_driver
#endif
-#ifdef CONFIG_MIPS_ALCHEMY
-#include "ohci-au1xxx.c"
-#define PLATFORM_DRIVER ohci_hcd_au1xxx_driver
-#endif
-
-#ifdef CONFIG_PNX8550
-#include "ohci-pnx8550.c"
-#define PLATFORM_DRIVER ohci_hcd_pnx8550_driver
-#endif
-
-#ifdef CONFIG_USB_OHCI_HCD_PPC_SOC
-#include "ohci-ppc-soc.c"
-#define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver
-#endif
-
#ifdef CONFIG_ARCH_AT91
#include "ohci-at91.c"
#define PLATFORM_DRIVER ohci_hcd_at91_driver
@@ -1059,11 +1145,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_da8xx_driver
#endif
-#ifdef CONFIG_USB_OHCI_SH
-#include "ohci-sh.c"
-#define PLATFORM_DRIVER ohci_hcd_sh_driver
-#endif
-
#ifdef CONFIG_USB_OHCI_HCD_PPC_OF
#include "ohci-ppc-of.c"
@@ -1105,16 +1186,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_tilegx_driver
#endif
-#ifdef CONFIG_USB_CNS3XXX_OHCI
-#include "ohci-cns3xxx.c"
-#define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
-#endif
-
-#ifdef CONFIG_CPU_XLR
-#include "ohci-xls.c"
-#define PLATFORM_DRIVER ohci_xls_driver
-#endif
-
#ifdef CONFIG_USB_OHCI_HCD_PLATFORM
#include "ohci-platform.c"
#define PLATFORM_DRIVER ohci_platform_driver
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 2f3619eefef..db09dae7b55 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -316,48 +316,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
return rc;
}
-/* Carry out the final steps of resuming the controller device */
-static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int port;
- bool need_reinit = false;
-
- /* See if the controller is already running or has been reset */
- ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
- if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
- need_reinit = true;
- } else {
- switch (ohci->hc_control & OHCI_CTRL_HCFS) {
- case OHCI_USB_OPER:
- case OHCI_USB_RESET:
- need_reinit = true;
- }
- }
-
- /* If needed, reinitialize and suspend the root hub */
- if (need_reinit) {
- spin_lock_irq(&ohci->lock);
- ohci_rh_resume(ohci);
- ohci_rh_suspend(ohci, 0);
- spin_unlock_irq(&ohci->lock);
- }
-
- /* Normally just turn on port power and enable interrupts */
- else {
- ohci_dbg(ohci, "powerup ports\n");
- for (port = 0; port < ohci->num_ports; port++)
- ohci_writel(ohci, RH_PS_PPS,
- &ohci->regs->roothub.portstatus[port]);
-
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
- ohci_readl(ohci, &ohci->regs->intrenable);
- msleep(20);
- }
-
- usb_hcd_resume_root_hub(hcd);
-}
-
/* Carry out polling-, autostop-, and autoresume-related state changes */
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
int any_connected, int rhsc_status)
diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c
index 931d588c3fb..8062bb9dea1 100644
--- a/drivers/usb/host/ohci-jz4740.c
+++ b/drivers/usb/host/ohci-jz4740.c
@@ -145,7 +145,7 @@ static const struct hc_driver ohci_jz4740_hc_driver = {
};
-static __devinit int jz4740_ohci_probe(struct platform_device *pdev)
+static int jz4740_ohci_probe(struct platform_device *pdev)
{
int ret;
struct usb_hcd *hcd;
@@ -239,7 +239,7 @@ err_free:
return ret;
}
-static __devexit int jz4740_ohci_remove(struct platform_device *pdev)
+static int jz4740_ohci_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd);
@@ -266,7 +266,7 @@ static __devexit int jz4740_ohci_remove(struct platform_device *pdev)
static struct platform_driver ohci_hcd_jz4740_driver = {
.probe = jz4740_ohci_probe,
- .remove = __devexit_p(jz4740_ohci_remove),
+ .remove = jz4740_ohci_remove,
.driver = {
.name = "jz4740-ohci",
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
index e068f034cb9..2344040c16d 100644
--- a/drivers/usb/host/ohci-nxp.c
+++ b/drivers/usb/host/ohci-nxp.c
@@ -147,7 +147,7 @@ static void nxp_stop_hc(void)
__raw_writel(tmp, USB_OTG_STAT_CONTROL);
}
-static int __devinit ohci_nxp_start(struct usb_hcd *hcd)
+static int ohci_nxp_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
@@ -205,7 +205,7 @@ static const struct hc_driver ohci_nxp_hc_driver = {
.start_port_reset = ohci_start_port_reset,
};
-static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
+static int usb_hcd_nxp_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd = 0;
struct ohci_hcd *ohci;
diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c
index d469bf9b9e5..d44430d009f 100644
--- a/drivers/usb/host/ohci-octeon.c
+++ b/drivers/usb/host/ohci-octeon.c
@@ -42,7 +42,7 @@ static void ohci_octeon_hw_stop(void)
octeon2_usb_clocks_stop();
}
-static int __devinit ohci_octeon_start(struct usb_hcd *hcd)
+static int ohci_octeon_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 4531d03503c..b1d32fb4a7a 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -25,7 +25,6 @@
#include <asm/mach-types.h>
#include <mach/mux.h>
-#include <plat/fpga.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
@@ -93,14 +92,14 @@ static int omap_ohci_transceiver_power(int on)
{
if (on) {
if (machine_is_omap_innovator() && cpu_is_omap1510())
- fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL)
+ __raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL)
| ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL);
else if (machine_is_omap_osk())
tps65010_set_gpio_out_value(GPIO1, LOW);
} else {
if (machine_is_omap_innovator() && cpu_is_omap1510())
- fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL)
+ __raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL)
& ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL);
else if (machine_is_omap_osk())
@@ -530,7 +529,7 @@ static int ohci_omap_resume(struct platform_device *dev)
ohci->next_statechange = jiffies;
omap_ohci_clock_power(1);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 1b8133b6e45..eb35d963023 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -30,7 +30,6 @@
*/
#include <linux/platform_device.h>
-#include <plat/usb.h>
#include <linux/pm_runtime.h>
/*-------------------------------------------------------------------------*/
@@ -125,7 +124,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
-static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
+static int ohci_hcd_omap3_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usb_hcd *hcd = NULL;
@@ -209,7 +208,7 @@ err_io:
* the HCD's stop() method. It is always called from a thread
* context, normally "rmmod", "apmd", or something similar.
*/
-static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev)
+static int ohci_hcd_omap3_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -232,7 +231,7 @@ static void ohci_hcd_omap3_shutdown(struct platform_device *pdev)
static struct platform_driver ohci_hcd_omap3_driver = {
.probe = ohci_hcd_omap3_probe,
- .remove = __devexit_p(ohci_hcd_omap3_remove),
+ .remove = ohci_hcd_omap3_remove,
.shutdown = ohci_hcd_omap3_shutdown,
.driver = {
.name = "ohci-omap3",
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 1843bb68ac7..951514ef446 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -270,7 +270,7 @@ static int ohci_pci_reset (struct usb_hcd *hcd)
}
-static int __devinit ohci_pci_start (struct usb_hcd *hcd)
+static int ohci_pci_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ret;
@@ -296,49 +296,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
return ret;
}
-#ifdef CONFIG_PM
-
-static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- unsigned long flags;
- int rc = 0;
-
- /* Root hub was already suspended. Disable irq emission and
- * mark HW unaccessible, bail out if RH has been resumed. Use
- * the spinlock to properly synchronize with possible pending
- * RH suspend or resume activity.
- */
- spin_lock_irqsave (&ohci->lock, flags);
- if (ohci->rh_state != OHCI_RH_SUSPENDED) {
- rc = -EINVAL;
- goto bail;
- }
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
- (void)ohci_readl(ohci, &ohci->regs->intrdisable);
-
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- bail:
- spin_unlock_irqrestore (&ohci->lock, flags);
-
- return rc;
-}
-
-
-static int ohci_pci_resume(struct usb_hcd *hcd, bool hibernated)
-{
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- /* Make sure resume from hibernation re-enumerates everything */
- if (hibernated)
- ohci_usb_reset(hcd_to_ohci(hcd));
-
- ohci_finish_controller_resume(hcd);
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
/*-------------------------------------------------------------------------*/
@@ -362,8 +319,8 @@ static const struct hc_driver ohci_pci_hc_driver = {
.shutdown = ohci_shutdown,
#ifdef CONFIG_PM
- .pci_suspend = ohci_pci_suspend,
- .pci_resume = ohci_pci_resume,
+ .pci_suspend = ohci_suspend,
+ .pci_resume = ohci_resume,
#endif
/*
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index e24ec9f7916..084503b03fc 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -31,6 +31,10 @@ static int ohci_platform_reset(struct usb_hcd *hcd)
ohci->flags |= OHCI_QUIRK_FRAME_NO;
ohci_hcd_init(ohci);
+
+ if (pdata->num_ports)
+ ohci->num_ports = pdata->num_ports;
+
err = ohci_init(ohci);
return err;
@@ -79,7 +83,7 @@ static const struct hc_driver ohci_platform_hc_driver = {
.start_port_reset = ohci_start_port_reset,
};
-static int __devinit ohci_platform_probe(struct platform_device *dev)
+static int ohci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
@@ -97,13 +101,13 @@ static int __devinit ohci_platform_probe(struct platform_device *dev)
irq = platform_get_irq(dev, 0);
if (irq < 0) {
- pr_err("no irq provided");
+ dev_err(&dev->dev, "no irq provided");
return irq;
}
res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res_mem) {
- pr_err("no memory recourse provided");
+ dev_err(&dev->dev, "no memory resource provided");
return -ENXIO;
}
@@ -123,29 +127,19 @@ static int __devinit ohci_platform_probe(struct platform_device *dev)
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_err("controller already in use");
- err = -EBUSY;
- goto err_put_hcd;
- }
-
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_request_and_ioremap(&dev->dev, res_mem);
if (!hcd->regs) {
err = -ENOMEM;
- goto err_release_region;
+ goto err_put_hcd;
}
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_iounmap;
+ goto err_put_hcd;
platform_set_drvdata(dev, hcd);
return err;
-err_iounmap:
- iounmap(hcd->regs);
-err_release_region:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put_hcd:
usb_put_hcd(hcd);
err_power:
@@ -155,14 +149,12 @@ err_power:
return err;
}
-static int __devexit ohci_platform_remove(struct platform_device *dev)
+static int ohci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct usb_ohci_pdata *pdata = dev->dev.platform_data;
usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
platform_set_drvdata(dev, NULL);
@@ -199,7 +191,7 @@ static int ohci_platform_resume(struct device *dev)
return err;
}
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -222,7 +214,7 @@ static const struct dev_pm_ops ohci_platform_pm_ops = {
static struct platform_driver ohci_platform_driver = {
.id_table = ohci_platform_table,
.probe = ohci_platform_probe,
- .remove = __devexit_p(ohci_platform_remove),
+ .remove = ohci_platform_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c
deleted file mode 100644
index 148d27d6a67..00000000000
--- a/drivers/usb/host/ohci-pnx8550.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Copyright 2002 Hewlett-Packard Company
- * (C) Copyright 2005 Embedded Alley Solutions, Inc.
- *
- * Bus Glue for PNX8550
- *
- * Written by Christopher Hoover <ch@hpl.hp.com>
- * Based on fragments of previous driver by Russell King et al.
- *
- * Modified for LH7A404 from ohci-sa1111.c
- * by Durgesh Pattamatta <pattamattad@sharpsec.com>
- *
- * Modified for PNX8550 from ohci-sa1111.c and sa-omap.c
- * by Vitaly Wool <vitalywool@gmail.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <asm/mach-pnx8550/usb.h>
-#include <asm/mach-pnx8550/int.h>
-#include <asm/mach-pnx8550/pci.h>
-
-#ifndef CONFIG_PNX8550
-#error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined."
-#endif
-
-extern int usb_disabled(void);
-
-/*-------------------------------------------------------------------------*/
-
-static void pnx8550_start_hc(struct platform_device *dev)
-{
- /*
- * Set register CLK48CTL to enable and 48MHz
- */
- outl(0x00000003, PCI_BASE | 0x0004770c);
-
- /*
- * Set register CLK12CTL to enable and 48MHz
- */
- outl(0x00000003, PCI_BASE | 0x00047710);
-
- udelay(100);
-}
-
-static void pnx8550_stop_hc(struct platform_device *dev)
-{
- udelay(10);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
-
-/**
- * usb_hcd_pnx8550_probe - initialize pnx8550-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- */
-int usb_hcd_pnx8550_probe (const struct hc_driver *driver,
- struct platform_device *dev)
-{
- int retval;
- struct usb_hcd *hcd;
-
- if (dev->resource[0].flags != IORESOURCE_MEM ||
- dev->resource[1].flags != IORESOURCE_IRQ) {
- dev_err (&dev->dev,"invalid resource type\n");
- return -ENOMEM;
- }
-
- hcd = usb_create_hcd (driver, &dev->dev, "pnx8550");
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = dev->resource[0].start;
- hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] "
- "failed\n", hcd->rsrc_start, hcd->rsrc_len);
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n",
- hcd->rsrc_start, hcd->rsrc_len);
- retval = -ENOMEM;
- goto err2;
- }
-
- pnx8550_start_hc(dev);
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
- if (retval == 0)
- return retval;
-
- pnx8550_stop_hc(dev);
- iounmap(hcd->regs);
- err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs
- * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking
- * the HCD's stop() method. It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev)
-{
- usb_remove_hcd(hcd);
- pnx8550_stop_hc(dev);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int __devinit
-ohci_pnx8550_start (struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
- ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci);
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run (ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s",
- hcd->self.bus_name);
- ohci_stop (hcd);
- return ret;
- }
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_pnx8550_hc_driver = {
- .description = hcd_name,
- .product_desc = "PNX8550 OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_pnx8550_start,
- .stop = ohci_stop,
-
- /*
- * 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,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_pnx8550_drv_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev);
- return ret;
-}
-
-static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_hcd_pnx8550_remove(hcd, pdev);
- return 0;
-}
-
-MODULE_ALIAS("platform:pnx8550-ohci");
-
-static struct platform_driver ohci_hcd_pnx8550_driver = {
- .driver = {
- .name = "pnx8550-ohci",
- .owner = THIS_MODULE,
- },
- .probe = ohci_hcd_pnx8550_drv_probe,
- .remove = ohci_hcd_pnx8550_drv_remove,
-};
-
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index e27d5ae2b9e..64c2ed9ff95 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -19,7 +19,7 @@
#include <asm/prom.h>
-static int __devinit
+static int
ohci_ppc_of_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
@@ -81,7 +81,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = {
};
-static int __devinit ohci_hcd_ppc_of_probe(struct platform_device *op)
+static int ohci_hcd_ppc_of_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
deleted file mode 100644
index 185c39ed81b..00000000000
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Copyright 2002 Hewlett-Packard Company
- * (C) Copyright 2003-2005 MontaVista Software Inc.
- *
- * Bus Glue for PPC On-Chip OHCI driver
- * Tested on Freescale MPC5200 and IBM STB04xxx
- *
- * Modified by Dale Farnsworth <dale@farnsworth.org> from ohci-sa1111.c
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
-/**
- * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller.
- *
- * Store this function in the HCD's struct pci_driver as probe().
- */
-static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
- struct platform_device *pdev)
-{
- int retval;
- struct usb_hcd *hcd;
- struct ohci_hcd *ohci;
- struct resource *res;
- int irq;
-
- pr_debug("initializing PPC-SOC USB Controller\n");
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- pr_debug("%s: no irq\n", __FILE__);
- return -ENODEV;
- }
- irq = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- pr_debug("%s: no reg addr\n", __FILE__);
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(driver, &pdev->dev, "PPC-SOC USB");
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_debug("%s: request_mem_region failed\n", __FILE__);
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- pr_debug("%s: ioremap failed\n", __FILE__);
- retval = -ENOMEM;
- goto err2;
- }
-
- ohci = hcd_to_ohci(hcd);
- ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
-
-#ifdef CONFIG_PPC_MPC52xx
- /* MPC52xx doesn't need frame_no shift */
- ohci->flags |= OHCI_QUIRK_FRAME_NO;
-#endif
- ohci_hcd_init(ohci);
-
- retval = usb_add_hcd(hcd, irq, 0);
- if (retval == 0)
- return retval;
-
- pr_debug("Removing PPC-SOC USB Controller\n");
-
- iounmap(hcd->regs);
- err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_hcd_ppc_soc_remove - shutdown processing for On-Chip HCDs
- * @pdev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_ppc_soc_probe().
- * It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd,
- struct platform_device *pdev)
-{
- usb_remove_hcd(hcd);
-
- pr_debug("stopping PPC-SOC USB Controller\n");
-
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-}
-
-static int __devinit
-ohci_ppc_soc_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run(ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
-
- return 0;
-}
-
-static const struct hc_driver ohci_ppc_soc_hc_driver = {
- .description = hcd_name,
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_ppc_soc_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,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int ohci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- ret = usb_hcd_ppc_soc_probe(&ohci_ppc_soc_hc_driver, pdev);
- return ret;
-}
-
-static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_hcd_ppc_soc_remove(hcd, pdev);
- return 0;
-}
-
-static struct platform_driver ohci_hcd_ppc_soc_driver = {
- .probe = ohci_hcd_ppc_soc_drv_probe,
- .remove = ohci_hcd_ppc_soc_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
-#ifdef CONFIG_PM
- /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
- /*.resume = ohci_hcd_ppc_soc_drv_resume,*/
-#endif
- .driver = {
- .name = "ppc-soc-ohci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS("platform:ppc-soc-ohci");
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 2ee1d8d713d..7d35cd9e286 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -30,7 +30,7 @@ static int ps3_ohci_hc_reset(struct usb_hcd *hcd)
return ohci_init(ohci);
}
-static int __devinit ps3_ohci_hc_start(struct usb_hcd *hcd)
+static int ps3_ohci_hc_start(struct usb_hcd *hcd)
{
int result;
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
@@ -76,7 +76,7 @@ static const struct hc_driver ps3_ohci_hc_driver = {
#endif
};
-static int __devinit ps3_ohci_probe(struct ps3_system_bus_device *dev)
+static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
{
int result;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 2bf11440b01..efe71f3ca47 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -284,7 +284,7 @@ MODULE_DEVICE_TABLE(of, pxa_ohci_dt_ids);
static u64 pxa_ohci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit ohci_pxa_of_init(struct platform_device *pdev)
+static int ohci_pxa_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct pxaohci_platform_data *pdata;
@@ -330,7 +330,7 @@ static int __devinit ohci_pxa_of_init(struct platform_device *pdev)
return 0;
}
#else
-static int __devinit ohci_pxa_of_init(struct platform_device *pdev)
+static int ohci_pxa_of_init(struct platform_device *pdev)
{
return 0;
}
@@ -471,7 +471,7 @@ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-static int __devinit
+static int
ohci_pxa27x_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@@ -591,7 +591,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
/* Select Power Management Mode */
pxa27x_ohci_select_pmm(ohci, inf->port_mode);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index c5a1ea9145f..7482cfbe8c5 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -596,7 +596,6 @@ static void td_submit_urb (
urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C);
}
- urb_priv->td_cnt = 0;
list_add (&urb_priv->pending, &ohci->pending);
if (data_len)
@@ -672,7 +671,8 @@ static void td_submit_urb (
* we could often reduce the number of TDs here.
*/
case PIPE_ISOCHRONOUS:
- for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
+ for (cnt = urb_priv->td_cnt; cnt < urb->number_of_packets;
+ cnt++) {
int frame = urb->start_frame;
// FIXME scheduling should handle frame counter
@@ -1128,6 +1128,25 @@ dl_done_list (struct ohci_hcd *ohci)
while (td) {
struct td *td_next = td->next_dl_td;
+ struct ed *ed = td->ed;
+
+ /*
+ * Some OHCI controllers (NVIDIA for sure, maybe others)
+ * occasionally forget to add TDs to the done queue. Since
+ * TDs for a given endpoint are always processed in order,
+ * if we find a TD on the donelist then all of its
+ * predecessors must be finished as well.
+ */
+ for (;;) {
+ struct td *td2;
+
+ td2 = list_first_entry(&ed->td_list, struct td,
+ td_list);
+ if (td2 == td)
+ break;
+ takeback_td(ohci, td2);
+ }
+
takeback_td(ohci, td);
td = td_next;
}
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 0d2309ca471..ad0f5526960 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -323,8 +323,6 @@ usb_hcd_s3c2410_remove(struct usb_hcd *hcd, struct platform_device *dev)
{
usb_remove_hcd(hcd);
s3c2410_stop_hc(dev);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
}
@@ -353,35 +351,29 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
hcd->rsrc_start = dev->resource[0].start;
hcd->rsrc_len = resource_size(&dev->resource[0]);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- dev_err(&dev->dev, "request_mem_region failed\n");
- retval = -EBUSY;
+ hcd->regs = devm_request_and_ioremap(&dev->dev, &dev->resource[0]);
+ if (!hcd->regs) {
+ dev_err(&dev->dev, "devm_request_and_ioremap failed\n");
+ retval = -ENOMEM;
goto err_put;
}
- clk = clk_get(&dev->dev, "usb-host");
+ clk = devm_clk_get(&dev->dev, "usb-host");
if (IS_ERR(clk)) {
dev_err(&dev->dev, "cannot get usb-host clock\n");
retval = PTR_ERR(clk);
- goto err_mem;
+ goto err_put;
}
- usb_clk = clk_get(&dev->dev, "usb-bus-host");
+ usb_clk = devm_clk_get(&dev->dev, "usb-bus-host");
if (IS_ERR(usb_clk)) {
dev_err(&dev->dev, "cannot get usb-bus-host clock\n");
retval = PTR_ERR(usb_clk);
- goto err_clk;
+ goto err_put;
}
s3c2410_start_hc(dev, hcd);
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_err(&dev->dev, "ioremap failed\n");
- retval = -ENOMEM;
- goto err_ioremap;
- }
-
ohci_hcd_init(hcd_to_ohci(hcd));
retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
@@ -392,14 +384,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
err_ioremap:
s3c2410_stop_hc(dev);
- iounmap(hcd->regs);
- clk_put(usb_clk);
-
- err_clk:
- clk_put(clk);
-
- err_mem:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put:
usb_put_hcd(hcd);
@@ -474,12 +458,12 @@ static const struct hc_driver ohci_s3c2410_hc_driver = {
/* device driver */
-static int __devinit ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
+static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
{
return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev);
}
-static int __devexit ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)
+static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -524,8 +508,7 @@ static int ohci_hcd_s3c2410_drv_resume(struct device *dev)
s3c2410_start_hc(pdev, hcd);
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -541,7 +524,7 @@ static const struct dev_pm_ops ohci_hcd_s3c2410_pm_ops = {
static struct platform_driver ohci_hcd_s3c2410_driver = {
.probe = ohci_hcd_s3c2410_drv_probe,
- .remove = __devexit_p(ohci_hcd_s3c2410_drv_remove),
+ .remove = ohci_hcd_s3c2410_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index b6cc9252092..17b2a7dad77 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -63,7 +63,7 @@ static int ohci_sa1111_reset(struct usb_hcd *hcd)
return ohci_init(ohci);
}
-static int __devinit ohci_sa1111_start(struct usb_hcd *hcd)
+static int ohci_sa1111_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c
deleted file mode 100644
index 76a20c27836..00000000000
--- a/drivers/usb/host/ohci-sh.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- *
- * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <linux/platform_device.h>
-
-static int ohci_sh_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
- ohci_hcd_init(ohci);
- ohci_init(ohci);
- ohci_run(ohci);
- return 0;
-}
-
-static const struct hc_driver ohci_sh_hc_driver = {
- .description = hcd_name,
- .product_desc = "SuperH OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_sh_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,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_sh_probe(struct platform_device *pdev)
-{
- struct resource *res = NULL;
- struct usb_hcd *hcd = NULL;
- int irq = -1;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "platform_get_resource error.\n");
- return -ENODEV;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "platform_get_irq error.\n");
- return -ENODEV;
- }
-
- /* initialize hcd */
- hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name);
- if (!hcd) {
- dev_err(&pdev->dev, "Failed to create hcd\n");
- return -ENOMEM;
- }
-
- hcd->regs = (void __iomem *)res->start;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret != 0) {
- dev_err(&pdev->dev, "Failed to add hcd\n");
- usb_put_hcd(hcd);
- return ret;
- }
-
- return ret;
-}
-
-static int ohci_hcd_sh_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ohci_hcd_sh_driver = {
- .probe = ohci_hcd_sh_probe,
- .remove = ohci_hcd_sh_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "sh_ohci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS("platform:sh_ohci");
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index 5596ac2ba1c..3b5b908fd47 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -238,7 +238,7 @@ static int ohci_sm501_resume(struct platform_device *pdev)
ohci->next_statechange = jiffies;
sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#else
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index fc7305ee3c9..9020bf0e2ec 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -33,7 +33,7 @@ static void spear_stop_ohci(struct spear_ohci *ohci)
clk_disable_unprepare(ohci->clk);
}
-static int __devinit ohci_spear_start(struct usb_hcd *hcd)
+static int ohci_spear_start(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int ret;
@@ -101,13 +101,11 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
struct spear_ohci *ohci_p;
struct resource *res;
int retval, irq;
- char clk_name[20] = "usbh_clk";
- static int instance = -1;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
retval = irq;
- goto fail_irq_get;
+ goto fail;
}
/*
@@ -118,47 +116,39 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &spear_ohci_dma_mask;
- /*
- * Increment the device instance, when probing via device-tree
- */
- if (pdev->id < 0)
- instance++;
- else
- instance = pdev->id;
- sprintf(clk_name, "usbh.%01d_clk", instance);
-
- usbh_clk = clk_get(NULL, clk_name);
+ usbh_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(usbh_clk)) {
dev_err(&pdev->dev, "Error getting interface clock\n");
retval = PTR_ERR(usbh_clk);
- goto fail_get_usbh_clk;
+ goto fail;
}
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
retval = -ENOMEM;
- goto fail_create_hcd;
+ goto fail;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
retval = -ENODEV;
- goto fail_request_resource;
+ goto err_put_hcd;
}
hcd->rsrc_start = pdev->resource[0].start;
hcd->rsrc_len = resource_size(res);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len,
+ hcd_name)) {
dev_dbg(&pdev->dev, "request_mem_region failed\n");
retval = -EBUSY;
- goto fail_request_resource;
+ goto err_put_hcd;
}
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
dev_dbg(&pdev->dev, "ioremap failed\n");
retval = -ENOMEM;
- goto fail_ioremap;
+ goto err_put_hcd;
}
ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
@@ -171,15 +161,9 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
return retval;
spear_stop_ohci(ohci_p);
- iounmap(hcd->regs);
-fail_ioremap:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-fail_request_resource:
+err_put_hcd:
usb_put_hcd(hcd);
-fail_create_hcd:
- clk_put(usbh_clk);
-fail_get_usbh_clk:
-fail_irq_get:
+fail:
dev_err(&pdev->dev, "init fail, %d\n", retval);
return retval;
@@ -194,12 +178,8 @@ static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
if (ohci_p->clk)
spear_stop_ohci(ohci_p);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
- if (ohci_p->clk)
- clk_put(ohci_p->clk);
platform_set_drvdata(pdev, NULL);
return 0;
}
@@ -231,12 +211,12 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
ohci->next_statechange = jiffies;
spear_start_ohci(ohci_p);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#endif
-static struct of_device_id spear_ohci_id_table[] __devinitdata = {
+static struct of_device_id spear_ohci_id_table[] = {
{ .compatible = "st,spear600-ohci", },
{ },
};
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index 60c2b0722f2..5e3a6deb62b 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -128,7 +128,8 @@ static void tmio_start_hc(struct platform_device *dev)
tmio_iowrite8(2, tmio->ccr + CCR_INTC);
dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n",
- tmio_ioread8(tmio->ccr + CCR_REVID), hcd->rsrc_start, hcd->irq);
+ tmio_ioread8(tmio->ccr + CCR_REVID),
+ (u64) hcd->rsrc_start, hcd->irq);
}
static int ohci_tmio_start(struct usb_hcd *hcd)
@@ -184,7 +185,7 @@ static const struct hc_driver ohci_tmio_hc_driver = {
/*-------------------------------------------------------------------------*/
static struct platform_driver ohci_hcd_tmio_driver;
-static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
+static int ohci_hcd_tmio_drv_probe(struct platform_device *dev)
{
const struct mfd_cell *cell = mfd_get_cell(dev);
struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
@@ -271,7 +272,7 @@ err_usb_create_hcd:
return ret;
}
-static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev)
+static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct tmio_hcd *tmio = hcd_to_tmio(hcd);
@@ -352,7 +353,7 @@ static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
spin_unlock_irqrestore(&tmio->lock, flags);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
@@ -363,7 +364,7 @@ static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
static struct platform_driver ohci_hcd_tmio_driver = {
.probe = ohci_hcd_tmio_drv_probe,
- .remove = __devexit_p(ohci_hcd_tmio_drv_remove),
+ .remove = ohci_hcd_tmio_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
.suspend = ohci_hcd_tmio_drv_suspend,
.resume = ohci_hcd_tmio_drv_resume,
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c
deleted file mode 100644
index 84201cd1a47..00000000000
--- a/drivers/usb/host/ohci-xls.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * OHCI HCD for Netlogic XLS processors.
- *
- * (C) Copyright 2011 Netlogic Microsystems Inc.
- *
- * Based on ohci-au1xxx.c, and other Linux OHCI drivers.
- *
- * 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.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-static int ohci_xls_probe_internal(const struct hc_driver *driver,
- struct platform_device *dev)
-{
- struct resource *res;
- struct usb_hcd *hcd;
- int retval, irq;
-
- /* Get our IRQ from an earlier registered Platform Resource */
- irq = platform_get_irq(dev, 0);
- if (irq < 0) {
- dev_err(&dev->dev, "Found HC with no IRQ\n");
- return -ENODEV;
- }
-
- /* Get our Memory Handle */
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&dev->dev, "MMIO Handle incorrect!\n");
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(driver, &dev->dev, "XLS");
- if (!hcd) {
- retval = -ENOMEM;
- goto err1;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(&dev->dev, "Controller already in use\n");
- retval = -EBUSY;
- goto err2;
- }
-
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
- if (hcd->regs == NULL) {
- dev_dbg(&dev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err3;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval != 0)
- goto err4;
- return retval;
-
-err4:
- iounmap(hcd->regs);
-err3:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err2:
- usb_put_hcd(hcd);
-err1:
- dev_err(&dev->dev, "init fail, %d\n", retval);
- return retval;
-}
-
-static int ohci_xls_reset(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
- ohci_hcd_init(ohci);
- return ohci_init(ohci);
-}
-
-static int __devinit ohci_xls_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci;
- int ret;
-
- ohci = hcd_to_ohci(hcd);
- ret = ohci_run(ohci);
- if (ret < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
- return 0;
-}
-
-static struct hc_driver ohci_xls_hc_driver = {
- .description = hcd_name,
- .product_desc = "XLS OHCI Host Controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
- .irq = ohci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
- .reset = ohci_xls_reset,
- .start = ohci_xls_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
- .get_frame_number = ohci_get_frame,
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int ohci_xls_probe(struct platform_device *dev)
-{
- int ret;
-
- pr_debug("In ohci_xls_probe");
- if (usb_disabled())
- return -ENODEV;
- ret = ohci_xls_probe_internal(&ohci_xls_hc_driver, dev);
- return ret;
-}
-
-static int ohci_xls_remove(struct platform_device *dev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(dev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- return 0;
-}
-
-static struct platform_driver ohci_xls_driver = {
- .probe = ohci_xls_probe,
- .remove = ohci_xls_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ohci-xls-0",
- .owner = THIS_MODULE,
- },
-};
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 39f9e4a9a2d..a3b6d7104ae 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -443,7 +443,7 @@ static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
-static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
+static void quirk_usb_handoff_uhci(struct pci_dev *pdev)
{
unsigned long base = 0;
int i;
@@ -461,12 +461,12 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
uhci_check_and_reset_hc(pdev, base);
}
-static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
+static int mmio_resource_enabled(struct pci_dev *pdev, int idx)
{
return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
}
-static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
{
void __iomem *base;
u32 control;
@@ -533,7 +533,7 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
iounmap(base);
}
-static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = {
+static const struct dmi_system_id ehci_dmi_nohandoff_table[] = {
{
/* Pegatron Lucid (ExoPC) */
.matches = {
@@ -558,7 +558,7 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = {
{ }
};
-static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
+static void ehci_bios_handoff(struct pci_dev *pdev,
void __iomem *op_reg_base,
u32 cap, u8 offset)
{
@@ -626,7 +626,7 @@ static void __devinit ehci_bios_handoff(struct pci_dev *pdev,
writel(0, op_reg_base + EHCI_CONFIGFLAG);
}
-static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
+static void quirk_usb_disable_ehci(struct pci_dev *pdev)
{
void __iomem *base, *op_reg_base;
u32 hcc_params, cap, val;
@@ -723,6 +723,7 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done,
}
#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 0x8C31
+#define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI 0x9C31
bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev)
{
@@ -736,7 +737,8 @@ bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev)
{
return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
pdev->vendor == PCI_VENDOR_ID_INTEL &&
- pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI;
+ (pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI);
}
bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
@@ -841,7 +843,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports);
* and then waits 5 seconds for the BIOS to hand over control.
* If we timeout, assume the BIOS is broken and take control anyway.
*/
-static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
+static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
{
void __iomem *base;
int ext_cap_offset;
@@ -941,7 +943,7 @@ hc_init:
iounmap(base);
}
-static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
+static void quirk_usb_early_handoff(struct pci_dev *pdev)
{
/* Skip Netlogic mips SoC's internal PCI USB controller.
* This device does not need/support EHCI/OHCI handoff
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index fcc09e5ec0a..a6fd8f5371d 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2036,10 +2036,8 @@ static void collect_usb_address_map(struct usb_device *udev, unsigned long *map)
udev->parent->descriptor.bDeviceClass == USB_CLASS_HUB)
map[udev->devnum/32] |= (1 << (udev->devnum % 32));
- usb_hub_for_each_child(udev, chix, childdev) {
- if (childdev)
- collect_usb_address_map(childdev, map);
- }
+ usb_hub_for_each_child(udev, chix, childdev)
+ collect_usb_address_map(childdev, map);
}
/* this function must be called with interrupt disabled */
@@ -2393,7 +2391,7 @@ static const struct dev_pm_ops r8a66597_dev_pm_ops = {
#define R8A66597_DEV_PM_OPS NULL
#endif
-static int __devexit r8a66597_remove(struct platform_device *pdev)
+static int r8a66597_remove(struct platform_device *pdev)
{
struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597);
@@ -2407,7 +2405,7 @@ static int __devexit r8a66597_remove(struct platform_device *pdev)
return 0;
}
-static int __devinit r8a66597_probe(struct platform_device *pdev)
+static int r8a66597_probe(struct platform_device *pdev)
{
char clk_name[8];
struct resource *res = NULL, *ires;
@@ -2534,7 +2532,7 @@ clean_up:
static struct platform_driver r8a66597_driver = {
.probe = r8a66597_probe,
- .remove = __devexit_p(r8a66597_remove),
+ .remove = r8a66597_remove,
.driver = {
.name = (char *) hcd_name,
.owner = THIS_MODULE,
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 619b05f42d4..d62f0404baa 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1595,7 +1595,7 @@ static struct hc_driver sl811h_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int __devexit
+static int
sl811h_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
@@ -1618,7 +1618,7 @@ sl811h_remove(struct platform_device *dev)
return 0;
}
-static int __devinit
+static int
sl811h_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
@@ -1808,7 +1808,7 @@ sl811h_resume(struct platform_device *dev)
/* this driver is exported so sl811_cs can depend on it */
struct platform_driver sl811h_driver = {
.probe = sl811h_probe,
- .remove = __devexit_p(sl811h_remove),
+ .remove = sl811h_remove,
.suspend = sl811h_suspend,
.resume = sl811h_resume,
diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c
index c2a29faba07..74af2c6287d 100644
--- a/drivers/usb/host/ssb-hcd.c
+++ b/drivers/usb/host/ssb-hcd.c
@@ -39,7 +39,7 @@ struct ssb_hcd_device {
u32 enable_flags;
};
-static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
+static void ssb_hcd_5354wa(struct ssb_device *dev)
{
#ifdef CONFIG_SSB_DRIVER_MIPS
/* Work around for 5354 failures */
@@ -53,7 +53,7 @@ static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
#endif
}
-static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
+static void ssb_hcd_usb20wa(struct ssb_device *dev)
{
if (dev->id.coreid == SSB_DEV_USB20_HOST) {
/*
@@ -80,7 +80,7 @@ static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
}
/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
-static u32 __devinit ssb_hcd_init_chip(struct ssb_device *dev)
+static u32 ssb_hcd_init_chip(struct ssb_device *dev)
{
u32 flags = 0;
@@ -101,8 +101,7 @@ static const struct usb_ehci_pdata ehci_pdata = {
static const struct usb_ohci_pdata ohci_pdata = {
};
-static struct platform_device * __devinit
-ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
+static struct platform_device *ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
{
struct platform_device *hci_dev;
struct resource hci_res[2];
@@ -148,7 +147,7 @@ err_alloc:
return ERR_PTR(ret);
}
-static int __devinit ssb_hcd_probe(struct ssb_device *dev,
+static int ssb_hcd_probe(struct ssb_device *dev,
const struct ssb_device_id *id)
{
int err, tmp;
@@ -207,7 +206,7 @@ err_free_usb_dev:
return err;
}
-static void __devexit ssb_hcd_remove(struct ssb_device *dev)
+static void ssb_hcd_remove(struct ssb_device *dev)
{
struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
struct platform_device *ohci_dev = usb_dev->ohci_dev;
@@ -221,7 +220,7 @@ static void __devexit ssb_hcd_remove(struct ssb_device *dev)
ssb_device_disable(dev, 0);
}
-static void __devexit ssb_hcd_shutdown(struct ssb_device *dev)
+static void ssb_hcd_shutdown(struct ssb_device *dev)
{
ssb_device_disable(dev, 0);
}
@@ -249,7 +248,7 @@ static int ssb_hcd_resume(struct ssb_device *dev)
#define ssb_hcd_resume NULL
#endif /* CONFIG_PM */
-static const struct ssb_device_id ssb_hcd_table[] __devinitconst = {
+static const struct ssb_device_id ssb_hcd_table[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
@@ -261,7 +260,7 @@ static struct ssb_driver ssb_hcd_driver = {
.name = KBUILD_MODNAME,
.id_table = ssb_hcd_table,
.probe = ssb_hcd_probe,
- .remove = __devexit_p(ssb_hcd_remove),
+ .remove = ssb_hcd_remove,
.shutdown = ssb_hcd_shutdown,
.suspend = ssb_hcd_suspend,
.resume = ssb_hcd_resume,
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index dbbd1ba2522..5efdffe3236 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -2990,7 +2990,7 @@ static struct hc_driver u132_hc_driver = {
* synchronously - but instead should immediately stop activity to the
* device and asynchronously call usb_remove_hcd()
*/
-static int __devexit u132_remove(struct platform_device *pdev)
+static int u132_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
if (hcd) {
@@ -3084,7 +3084,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
mutex_unlock(&u132->sw_lock);
}
-static int __devinit u132_probe(struct platform_device *pdev)
+static int u132_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
int retval;
@@ -3212,7 +3212,7 @@ static int u132_resume(struct platform_device *pdev)
*/
static struct platform_driver u132_platform_driver = {
.probe = u132_probe,
- .remove = __devexit_p(u132_remove),
+ .remove = u132_remove,
.suspend = u132_suspend,
.resume = u132_resume,
.driver = {
diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c
index f7a62138e3e..511bfc46dd7 100644
--- a/drivers/usb/host/uhci-grlib.c
+++ b/drivers/usb/host/uhci-grlib.c
@@ -85,7 +85,7 @@ static const struct hc_driver uhci_grlib_hc_driver = {
};
-static int __devinit uhci_hcd_grlib_probe(struct platform_device *op)
+static int uhci_hcd_grlib_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
struct usb_hcd *hcd;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 4b9e9aba266..4f64d24eebc 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -447,6 +447,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
return IRQ_NONE;
uhci_writew(uhci, status, USBSTS); /* Clear it */
+ spin_lock(&uhci->lock);
+ if (unlikely(!uhci->is_initialized)) /* not yet configured */
+ goto done;
+
if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
if (status & USBSTS_HSE)
dev_err(uhci_dev(uhci), "host system error, "
@@ -455,7 +459,6 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
dev_err(uhci_dev(uhci), "host controller process "
"error, something bad happened!\n");
if (status & USBSTS_HCH) {
- spin_lock(&uhci->lock);
if (uhci->rh_state >= UHCI_RH_RUNNING) {
dev_err(uhci_dev(uhci),
"host controller halted, "
@@ -473,15 +476,15 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
* pending unlinks */
mod_timer(&hcd->rh_timer, jiffies);
}
- spin_unlock(&uhci->lock);
}
}
- if (status & USBSTS_RD)
+ if (status & USBSTS_RD) {
+ spin_unlock(&uhci->lock);
usb_hcd_poll_rh_status(hcd);
- else {
- spin_lock(&uhci->lock);
+ } else {
uhci_scan_schedule(uhci);
+ done:
spin_unlock(&uhci->lock);
}
@@ -662,9 +665,9 @@ static int uhci_start(struct usb_hcd *hcd)
*/
mb();
+ spin_lock_irq(&uhci->lock);
configure_hc(uhci);
uhci->is_initialized = 1;
- spin_lock_irq(&uhci->lock);
start_rh(uhci);
spin_unlock_irq(&uhci->lock);
return 0;
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 68ebf20e151..8c4dace4b14 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -62,7 +62,7 @@ static const struct hc_driver uhci_platform_hc_driver = {
static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
-static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
+static int uhci_hcd_platform_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct uhci_hcd *uhci;
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index d2c6f5ac462..15921fd5504 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1256,7 +1256,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
struct uhci_qh *qh)
{
struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */
- int i, frame;
+ int i;
+ unsigned frame, next;
unsigned long destination, status;
struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
@@ -1265,37 +1266,29 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
urb->number_of_packets >= UHCI_NUMFRAMES)
return -EFBIG;
+ uhci_get_current_frame_number(uhci);
+
/* Check the period and figure out the starting frame number */
if (!qh->bandwidth_reserved) {
qh->period = urb->interval;
- if (urb->transfer_flags & URB_ISO_ASAP) {
- qh->phase = -1; /* Find the best phase */
- i = uhci_check_bandwidth(uhci, qh);
- if (i)
- return i;
-
- /* Allow a little time to allocate the TDs */
- uhci_get_current_frame_number(uhci);
- frame = uhci->frame_number + 10;
-
- /* Move forward to the first frame having the
- * correct phase */
- urb->start_frame = frame + ((qh->phase - frame) &
- (qh->period - 1));
- } else {
- i = urb->start_frame - uhci->last_iso_frame;
- if (i <= 0 || i >= UHCI_NUMFRAMES)
- return -EINVAL;
- qh->phase = urb->start_frame & (qh->period - 1);
- i = uhci_check_bandwidth(uhci, qh);
- if (i)
- return i;
- }
+ qh->phase = -1; /* Find the best phase */
+ i = uhci_check_bandwidth(uhci, qh);
+ if (i)
+ return i;
+
+ /* Allow a little time to allocate the TDs */
+ next = uhci->frame_number + 10;
+ frame = qh->phase;
+
+ /* Round up to the first available slot */
+ frame += (next - frame + qh->period - 1) & -qh->period;
} else if (qh->period != urb->interval) {
return -EINVAL; /* Can't change the period */
} else {
+ next = uhci->frame_number + 2;
+
/* Find the next unused frame */
if (list_empty(&qh->queue)) {
frame = qh->iso_frame;
@@ -1308,25 +1301,31 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
lurb->number_of_packets *
lurb->interval;
}
- if (urb->transfer_flags & URB_ISO_ASAP) {
- /* Skip some frames if necessary to insure
- * the start frame is in the future.
+
+ /* Fell behind? */
+ if (uhci_frame_before_eq(frame, next)) {
+
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ frame += (next - frame + qh->period - 1) &
+ -qh->period;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
*/
- uhci_get_current_frame_number(uhci);
- if (uhci_frame_before_eq(frame, uhci->frame_number)) {
- frame = uhci->frame_number + 1;
- frame += ((qh->phase - frame) &
- (qh->period - 1));
- }
- } /* Otherwise pick up where the last URB leaves off */
- urb->start_frame = frame;
+ else if (!uhci_frame_before_eq(next,
+ frame + (urb->number_of_packets - 1) *
+ qh->period))
+ return -EXDEV;
+ }
}
/* Make sure we won't have to go too far into the future */
if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES,
- urb->start_frame + urb->number_of_packets *
- urb->interval))
+ frame + urb->number_of_packets * urb->interval))
return -EFBIG;
+ urb->start_frame = frame;
status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a686cf4905b..68914429482 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -761,12 +761,39 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
break;
case USB_PORT_FEAT_LINK_STATE:
temp = xhci_readl(xhci, port_array[wIndex]);
+
+ /* Disable port */
+ if (link_state == USB_SS_PORT_LS_SS_DISABLED) {
+ xhci_dbg(xhci, "Disable port %d\n", wIndex);
+ temp = xhci_port_state_to_neutral(temp);
+ /*
+ * Clear all change bits, so that we get a new
+ * connection event.
+ */
+ temp |= PORT_CSC | PORT_PEC | PORT_WRC |
+ PORT_OCC | PORT_RC | PORT_PLC |
+ PORT_CEC;
+ xhci_writel(xhci, temp | PORT_PE,
+ port_array[wIndex]);
+ temp = xhci_readl(xhci, port_array[wIndex]);
+ break;
+ }
+
+ /* Put link in RxDetect (enable port) */
+ if (link_state == USB_SS_PORT_LS_RX_DETECT) {
+ xhci_dbg(xhci, "Enable port %d\n", wIndex);
+ xhci_set_link_state(xhci, port_array, wIndex,
+ link_state);
+ temp = xhci_readl(xhci, port_array[wIndex]);
+ break;
+ }
+
/* Software should not attempt to set
- * port link state above '5' (Rx.Detect) and the port
+ * port link state above '3' (U3) and the port
* must be enabled.
*/
if ((temp & PORT_PE) == 0 ||
- (link_state > USB_SS_PORT_LS_RX_DETECT)) {
+ (link_state > USB_SS_PORT_LS_U3)) {
xhci_warn(xhci, "Cannot set link state.\n");
goto error;
}
@@ -957,6 +984,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
int max_ports;
__le32 __iomem **port_array;
struct xhci_bus_state *bus_state;
+ bool reset_change = false;
max_ports = xhci_get_ports(hcd, &port_array);
bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -988,6 +1016,12 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
buf[(i + 1) / 8] |= 1 << (i + 1) % 8;
status = 1;
}
+ if ((temp & PORT_RC))
+ reset_change = true;
+ }
+ if (!status && !reset_change) {
+ xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
+ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
}
spin_unlock_irqrestore(&xhci->lock, flags);
return status ? retval : 0;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 487bc083dea..35616ffbe3a 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -205,7 +205,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
next = xhci_segment_alloc(xhci, cycle_state, flags);
if (!next) {
- xhci_free_segments_for_ring(xhci, *first);
+ prev = *first;
+ while (prev) {
+ next = prev->next;
+ xhci_segment_free(xhci, prev);
+ prev = next;
+ }
return -ENOMEM;
}
xhci_link_segments(xhci, prev, next, type);
@@ -258,7 +263,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
return ring;
fail:
- xhci_ring_free(xhci, ring);
+ kfree(ring);
return NULL;
}
@@ -1245,6 +1250,8 @@ static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
struct usb_host_endpoint *ep)
{
+ if (ep->desc.bInterval == 0)
+ return 0;
return xhci_microframes_to_exponent(udev, ep,
ep->desc.bInterval, 0, 15);
}
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 8345d7c2306..af259e0ec17 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -29,6 +29,7 @@
/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
+#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400
#define PCI_VENDOR_ID_ETRON 0x1b6f
#define PCI_DEVICE_ID_ASROCK_P67 0x7023
@@ -58,8 +59,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
/* Look for vendor-specific quirks */
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
- pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
- if (pdev->revision == 0x0) {
+ (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK ||
+ pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1400)) {
+ if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
+ pdev->revision == 0x0) {
xhci->quirks |= XHCI_RESET_EP_QUIRK;
xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
" endpoint cmd after reset endpoint\n");
@@ -218,15 +221,8 @@ static void xhci_pci_remove(struct pci_dev *dev)
static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- int retval = 0;
- if (hcd->state != HC_STATE_SUSPENDED ||
- xhci->shared_hcd->state != HC_STATE_SUSPENDED)
- return -EINVAL;
-
- retval = xhci_suspend(xhci);
-
- return retval;
+ return xhci_suspend(xhci);
}
static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 4e1a8946b8d..59fb5c677db 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -318,7 +318,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
* seconds), then it should assume that the there are
* larger problems with the xHC and assert HCRST.
*/
- ret = handshake(xhci, &xhci->op_regs->cmd_ring,
+ ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
if (ret < 0) {
xhci_err(xhci, "Stopped the command ring failed, "
@@ -1725,6 +1725,15 @@ cleanup:
if (bogus_port_status)
return;
+ /*
+ * xHCI port-status-change events occur when the "or" of all the
+ * status-change bits in the portsc register changes from 0 to 1.
+ * New status changes won't cause an event if any other change
+ * bits are still set. When an event occurs, switch over to
+ * polling to avoid losing status changes.
+ */
+ xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
+ set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
spin_unlock(&xhci->lock);
/* Pass this up to the core */
usb_hcd_poll_rh_status(hcd);
@@ -3071,11 +3080,11 @@ static u32 xhci_td_remainder(unsigned int remainder)
}
/*
- * For xHCI 1.0 host controllers, TD size is the number of packets remaining in
- * the TD (*not* including this TRB).
+ * For xHCI 1.0 host controllers, TD size is the number of max packet sized
+ * packets remaining in the TD (*not* including this TRB).
*
* Total TD packet count = total_packet_count =
- * roundup(TD size in bytes / wMaxPacketSize)
+ * DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
*
* Packets transferred up to and including this TRB = packets_transferred =
* rounddown(total bytes transferred including this TRB / wMaxPacketSize)
@@ -3083,15 +3092,16 @@ static u32 xhci_td_remainder(unsigned int remainder)
* TD size = total_packet_count - packets_transferred
*
* It must fit in bits 21:17, so it can't be bigger than 31.
+ * The last TRB in a TD must have the TD size set to zero.
*/
-
static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
- unsigned int total_packet_count, struct urb *urb)
+ unsigned int total_packet_count, struct urb *urb,
+ unsigned int num_trbs_left)
{
int packets_transferred;
/* One TRB with a zero-length data packet. */
- if (running_total == 0 && trb_buff_len == 0)
+ if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
return 0;
/* All the TRB queueing functions don't count the current TRB in
@@ -3100,7 +3110,9 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
packets_transferred = (running_total + trb_buff_len) /
usb_endpoint_maxp(&urb->ep->desc);
- return xhci_td_remainder(total_packet_count - packets_transferred);
+ if ((total_packet_count - packets_transferred) > 31)
+ return 31 << 17;
+ return (total_packet_count - packets_transferred) << 17;
}
static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
@@ -3127,7 +3139,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
num_trbs = count_sg_trbs_needed(xhci, urb);
num_sgs = urb->num_mapped_sgs;
- total_packet_count = roundup(urb->transfer_buffer_length,
+ total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
@@ -3210,7 +3222,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
- trb_buff_len, total_packet_count, urb);
+ trb_buff_len, total_packet_count, urb,
+ num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
@@ -3318,7 +3331,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
start_cycle = ep_ring->cycle_state;
running_total = 0;
- total_packet_count = roundup(urb->transfer_buffer_length,
+ total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
usb_endpoint_maxp(&urb->ep->desc));
/* How much data is in the first TRB? */
addr = (u64) urb->transfer_dma;
@@ -3364,7 +3377,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
running_total);
} else {
remainder = xhci_v1_0_td_remainder(running_total,
- trb_buff_len, total_packet_count, urb);
+ trb_buff_len, total_packet_count, urb,
+ num_trbs - 1);
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
@@ -3627,7 +3641,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
addr = start_addr + urb->iso_frame_desc[i].offset;
td_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len;
- total_packet_count = roundup(td_len,
+ total_packet_count = DIV_ROUND_UP(td_len,
usb_endpoint_maxp(&urb->ep->desc));
/* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0)
@@ -3706,7 +3720,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
} else {
remainder = xhci_v1_0_td_remainder(
running_total, trb_buff_len,
- total_packet_count, urb);
+ total_packet_count, urb,
+ (trbs_per_td - j - 1));
}
length_field = TRB_LEN(trb_buff_len) |
remainder |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index c9e419f29b7..f1f01a834ba 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
/* TODO: copied from ehci-hcd.c - can this be refactored? */
/*
- * handshake - spin reading hc until handshake completes or fails
+ * xhci_handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
* @mask: bits to look at in result of read
* @done: value of those bits when handshake succeeds
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
* handshake done). There are two failure modes: "usec" have passed (major
* hardware flakeout), or the register reads as all-ones (hardware removed).
*/
-int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
+int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec)
{
u32 result;
@@ -103,7 +103,7 @@ int xhci_halt(struct xhci_hcd *xhci)
xhci_dbg(xhci, "// Halt the HC\n");
xhci_quiesce(xhci);
- ret = handshake(xhci, &xhci->op_regs->status,
+ ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
if (!ret) {
xhci->xhc_state |= XHCI_STATE_HALTED;
@@ -132,7 +132,7 @@ static int xhci_start(struct xhci_hcd *xhci)
* Wait for the HCHalted Status bit to be 0 to indicate the host is
* running.
*/
- ret = handshake(xhci, &xhci->op_regs->status,
+ ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, 0, XHCI_MAX_HALT_USEC);
if (ret == -ETIMEDOUT)
xhci_err(xhci, "Host took too long to start, "
@@ -167,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci)
command |= CMD_RESET;
xhci_writel(xhci, command, &xhci->op_regs->command);
- ret = handshake(xhci, &xhci->op_regs->command,
+ ret = xhci_handshake(xhci, &xhci->op_regs->command,
CMD_RESET, 0, 10 * 1000 * 1000);
if (ret)
return ret;
@@ -177,7 +177,7 @@ int xhci_reset(struct xhci_hcd *xhci)
* xHCI cannot write to any doorbells or operational registers other
* than status until the "Controller Not Ready" flag is cleared.
*/
- ret = handshake(xhci, &xhci->op_regs->status,
+ ret = xhci_handshake(xhci, &xhci->op_regs->status,
STS_CNR, 0, 10 * 1000 * 1000);
for (i = 0; i < 2; ++i) {
@@ -480,7 +480,7 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
if (strstr(dmi_product_name, "Z420") ||
strstr(dmi_product_name, "Z620") ||
strstr(dmi_product_name, "Z820") ||
- strstr(dmi_product_name, "Z1"))
+ strstr(dmi_product_name, "Z1 Workstation"))
return true;
return false;
@@ -880,6 +880,15 @@ int xhci_suspend(struct xhci_hcd *xhci)
struct usb_hcd *hcd = xhci_to_hcd(xhci);
u32 command;
+ if (hcd->state != HC_STATE_SUSPENDED ||
+ xhci->shared_hcd->state != HC_STATE_SUSPENDED)
+ return -EINVAL;
+
+ /* Don't poll the roothubs on bus suspend. */
+ xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
+ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+ del_timer_sync(&hcd->rh_timer);
+
spin_lock_irq(&xhci->lock);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
@@ -890,7 +899,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
command = xhci_readl(xhci, &xhci->op_regs->command);
command &= ~CMD_RUN;
xhci_writel(xhci, command, &xhci->op_regs->command);
- if (handshake(xhci, &xhci->op_regs->status,
+ if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) {
xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
spin_unlock_irq(&xhci->lock);
@@ -905,7 +914,8 @@ int xhci_suspend(struct xhci_hcd *xhci)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_CSS;
xhci_writel(xhci, command, &xhci->op_regs->command);
- if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) {
+ if (xhci_handshake(xhci, &xhci->op_regs->status,
+ STS_SAVE, 0, 10 * 1000)) {
xhci_warn(xhci, "WARN: xHC save state timeout\n");
spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT;
@@ -967,7 +977,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_CRS;
xhci_writel(xhci, command, &xhci->op_regs->command);
- if (handshake(xhci, &xhci->op_regs->status,
+ if (xhci_handshake(xhci, &xhci->op_regs->status,
STS_RESTORE, 0, 10 * 1000)) {
xhci_warn(xhci, "WARN: xHC restore state timeout\n");
spin_unlock_irq(&xhci->lock);
@@ -1035,7 +1045,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_RUN;
xhci_writel(xhci, command, &xhci->op_regs->command);
- handshake(xhci, &xhci->op_regs->status, STS_HALT,
+ xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT,
0, 250 * 1000);
/* step 5: walk topology and initialize portsc,
@@ -1064,6 +1074,11 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
compliance_mode_recovery_timer_init(xhci);
+ /* Re-enable port polling. */
+ xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
+ set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+ usb_hcd_poll_rh_status(hcd);
+
return retval;
}
#endif /* CONFIG_PM */
@@ -2254,7 +2269,7 @@ static bool xhci_is_async_ep(unsigned int ep_type)
static bool xhci_is_sync_in_ep(unsigned int ep_type)
{
- return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP);
+ return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP);
}
static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw)
@@ -3874,7 +3889,8 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd,
spin_lock_irqsave(&xhci->lock, flags);
/* Check L1 Status */
- ret = handshake(xhci, pm_addr, PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
+ ret = xhci_handshake(xhci, pm_addr,
+ PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
if (ret != -ETIMEDOUT) {
/* enter L1 successfully */
temp = xhci_readl(xhci, addr);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 53df4e70ca0..f791bd0aee6 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1720,7 +1720,7 @@ static inline void xhci_unregister_plat(void)
/* xHCI host controller glue */
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
-int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
+int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
u32 mask, u32 done, int usec);
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci);