Merge 3.7-rc3 into usb-next.
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Oct 2012 16:04:39 +0000 (09:04 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Oct 2012 16:04:39 +0000 (09:04 -0700)
This pulls in all of the USB changes in 3.7-rc3 into usb-next and
resolves the merge issue with:
drivers/usb/misc/ezusb.c

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
75 files changed:
Documentation/usb/error-codes.txt
arch/arm/mach-cns3xxx/cns3420vb.c
arch/mips/alchemy/common/Makefile
arch/mips/alchemy/common/platform.c
arch/mips/alchemy/common/usb.c [new file with mode: 0644]
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1235_defconfig
arch/mips/configs/gpr_defconfig
arch/mips/configs/ls1b_defconfig
arch/mips/configs/mtx1_defconfig
arch/mips/loongson1/common/platform.c
arch/mips/netlogic/xlr/platform.c
arch/mips/pnx8550/common/platform.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4a/setup-sh7757.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
drivers/usb/core/devices.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/urb.c
drivers/usb/core/usb.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/alchemy-common.c [deleted file]
drivers/usb/host/ehci-au1xxx.c [deleted file]
drivers/usb/host/ehci-cns3xxx.c [deleted file]
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-ixp4xx.c [deleted file]
drivers/usb/host/ehci-lpm.c
drivers/usb/host/ehci-ls1x.c [deleted file]
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-platform.c
drivers/usb/host/ehci-s5p.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ehci-vt8500.c
drivers/usb/host/ehci-w90x900.c
drivers/usb/host/ehci-xls.c [deleted file]
drivers/usb/host/ehci.h
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-au1xxx.c [deleted file]
drivers/usb/host/ohci-cns3xxx.c [deleted file]
drivers/usb/host/ohci-ep93xx.c
drivers/usb/host/ohci-exynos.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-platform.c
drivers/usb/host/ohci-pnx8550.c [deleted file]
drivers/usb/host/ohci-ppc-soc.c [deleted file]
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-q.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/host/ohci-sh.c [deleted file]
drivers/usb/host/ohci-sm501.c
drivers/usb/host/ohci-spear.c
drivers/usb/host/ohci-tmio.c
drivers/usb/host/ohci-xls.c [deleted file]
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/uhci-q.c
drivers/usb/misc/ezusb.c
drivers/usb/phy/tegra_usb_phy.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/usb-skeleton.c
drivers/usb/wusbcore/devconnect.c
drivers/uwb/umc-bus.c
include/linux/usb.h
include/linux/usb/ehci_pdriver.h
include/linux/usb/ezusb.h
include/linux/usb/ohci_pdriver.h

index b3f606b81a03926e287a13afa443ed8cd44d47a7..8d1e2a9ebbba25a2736690877c524927eb96b0b1 100644 (file)
@@ -35,9 +35,8 @@ USB-specific:
                d) ISO: number_of_packets is < 0
                e) various other cases
 
--EAGAIN                a) specified ISO start frame too early
-               b) (using ISO-ASAP) too much scheduled for the future
-                  wait some time and try again.
+-EXDEV         ISO: URB_ISO_ASAP wasn't specified and all the frames
+               the URB would be scheduled in have already expired.
 
 -EFBIG         Host controller driver can't schedule that many ISO frames.
 
index 2c5fb4c7e509b8786fb1ba0d45cb974bc373f4d2..8a00cee8222802bdfacda361921f0f94b0497afd 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/gic.h>
@@ -32,6 +34,7 @@
 #include <asm/mach/time.h>
 #include <mach/cns3xxx.h>
 #include <mach/irqs.h>
+#include <mach/pm.h>
 #include "core.h"
 #include "devices.h"
 
@@ -125,13 +128,53 @@ static struct resource cns3xxx_usb_ehci_resources[] = {
 
 static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
 
+static int csn3xxx_usb_power_on(struct platform_device *pdev)
+{
+       /*
+        * 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);
+       }
+
+       return 0;
+}
+
+static void csn3xxx_usb_power_off(struct platform_device *pdev)
+{
+       /*
+        * 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);
+}
+
+static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
+       .port_power_off = 1,
+       .power_on       = csn3xxx_usb_power_on,
+       .power_off      = csn3xxx_usb_power_off,
+};
+
 static struct platform_device cns3xxx_usb_ehci_device = {
-       .name          = "cns3xxx-ehci",
+       .name          = "ehci-platform",
        .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
        .resource      = cns3xxx_usb_ehci_resources,
        .dev           = {
                .dma_mask          = &cns3xxx_usb_ehci_dma_mask,
                .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data     = &cns3xxx_usb_ehci_pdata,
        },
 };
 
@@ -149,13 +192,20 @@ static struct resource cns3xxx_usb_ohci_resources[] = {
 
 static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
 
+static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
+       .num_ports      = 1,
+       .power_on       = csn3xxx_usb_power_on,
+       .power_off      = csn3xxx_usb_power_off,
+};
+
 static struct platform_device cns3xxx_usb_ohci_device = {
-       .name          = "cns3xxx-ohci",
+       .name          = "ohci-platform",
        .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
        .resource      = cns3xxx_usb_ohci_resources,
        .dev           = {
                .dma_mask          = &cns3xxx_usb_ohci_dma_mask,
                .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data     = &cns3xxx_usb_ohci_pdata,
        },
 };
 
index 407ebc00e661f974bbaec96a345afcea8f6b6409..cb83d8d21aef33877d718b7494e0afa11b8b9a99 100644 (file)
@@ -6,7 +6,7 @@
 #
 
 obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
-       sleeper.o dma.o dbdma.o vss.o irq.o
+       sleeper.o dma.o dbdma.o vss.o irq.o usb.o
 
 # optional gpiolib support
 ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
index c0f3ce6dcb56d448bcb2184c5fdc2c61498a8d7c..7af941d8e717089cdb78b016368774a09e3bd4ef 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
 #include <linux/slab.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
 
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
@@ -122,6 +124,53 @@ static void __init alchemy_setup_uarts(int ctype)
 static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
 static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
 
+/* Power on callback for the ehci platform driver */
+static int alchemy_ehci_power_on(struct platform_device *pdev)
+{
+       return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
+}
+
+/* Power off/suspend callback for the ehci platform driver */
+static void alchemy_ehci_power_off(struct platform_device *pdev)
+{
+       alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
+}
+
+static struct usb_ehci_pdata alchemy_ehci_pdata = {
+       .no_io_watchdog = 1,
+       .power_on       = alchemy_ehci_power_on,
+       .power_off      = alchemy_ehci_power_off,
+       .power_suspend  = alchemy_ehci_power_off,
+};
+
+/* Power on callback for the ohci platform driver */
+static int alchemy_ohci_power_on(struct platform_device *pdev)
+{
+       int unit;
+
+       unit = (pdev->id == 1) ?
+               ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
+
+       return alchemy_usb_control(unit, 1);
+}
+
+/* Power off/suspend callback for the ohci platform driver */
+static void alchemy_ohci_power_off(struct platform_device *pdev)
+{
+       int unit;
+
+       unit = (pdev->id == 1) ?
+               ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
+
+       alchemy_usb_control(unit, 0);
+}
+
+static struct usb_ohci_pdata alchemy_ohci_pdata = {
+       .power_on               = alchemy_ohci_power_on,
+       .power_off              = alchemy_ohci_power_off,
+       .power_suspend          = alchemy_ohci_power_off,
+};
+
 static unsigned long alchemy_ohci_data[][2] __initdata = {
        [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT },
        [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT },
@@ -169,9 +218,10 @@ static void __init alchemy_setup_usb(int ctype)
        res[1].start = alchemy_ohci_data[ctype][1];
        res[1].end = res[1].start;
        res[1].flags = IORESOURCE_IRQ;
-       pdev->name = "au1xxx-ohci";
+       pdev->name = "ohci-platform";
        pdev->id = 0;
        pdev->dev.dma_mask = &alchemy_ohci_dmamask;
+       pdev->dev.platform_data = &alchemy_ohci_pdata;
 
        if (platform_device_register(pdev))
                printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
@@ -188,9 +238,10 @@ static void __init alchemy_setup_usb(int ctype)
                res[1].start = alchemy_ehci_data[ctype][1];
                res[1].end = res[1].start;
                res[1].flags = IORESOURCE_IRQ;
-               pdev->name = "au1xxx-ehci";
+               pdev->name = "ehci-platform";
                pdev->id = 0;
                pdev->dev.dma_mask = &alchemy_ehci_dmamask;
+               pdev->dev.platform_data = &alchemy_ehci_pdata;
 
                if (platform_device_register(pdev))
                        printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
@@ -207,9 +258,10 @@ static void __init alchemy_setup_usb(int ctype)
                res[1].start = AU1300_USB_INT;
                res[1].end = res[1].start;
                res[1].flags = IORESOURCE_IRQ;
-               pdev->name = "au1xxx-ohci";
+               pdev->name = "ohci-platform";
                pdev->id = 1;
                pdev->dev.dma_mask = &alchemy_ohci_dmamask;
+               pdev->dev.platform_data = &alchemy_ohci_pdata;
 
                if (platform_device_register(pdev))
                        printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c
new file mode 100644 (file)
index 0000000..936af83
--- /dev/null
@@ -0,0 +1,614 @@
+/*
+ * 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);
index 17a36c12517296f95f772396670f0610a7f29b86..face9d26e6d5a1558c93cd149e60eb742fad8619 100644 (file)
@@ -233,6 +233,7 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_EHCI_TT_NEWSCHED=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
 CONFIG_USB_UHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_NEW_LEDS=y
index c48998ffd198ebc8c34d6d90b6887019a566ed8b..14752dde754018170930faa0aabfbd049b2a4312 100644 (file)
@@ -346,8 +346,10 @@ CONFIG_USB=y
 CONFIG_USB_DYNAMIC_MINORS=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_CLKGATE=y
index 48a40aefaf58fa615985e2f41eb07b7c2dbf04d6..fb64589015fc2bb6841e4e23676d030003590940 100644 (file)
@@ -291,6 +291,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
 CONFIG_USB_STORAGE=m
 CONFIG_USB_LIBUSUAL=y
 CONFIG_USB_SERIAL=y
index 80cff8bea8e82beddd5dde7b13aa0610c7799799..7eb75543ca1a23b5be78e89ae3ec33b0f3d446db 100644 (file)
@@ -76,6 +76,7 @@ CONFIG_HID_GENERIC=m
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
 CONFIG_USB_STORAGE=m
 CONFIG_USB_SERIAL=m
index 46c61edcdf7b68440e54ce6d6032daa5075f7685..459018acb618490210d6b102410d8f503a7467ca 100644 (file)
@@ -581,6 +581,7 @@ CONFIG_USB_MON=m
 CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PLATFORM=y
 CONFIG_USB_UHCI_HCD=m
 CONFIG_USB_U132_HCD=m
 CONFIG_USB_SL811_HCD=m
index e92d59c4bd789e783809a5ed15e3e19c7f965ced..2874bf224418348f42432c631f1928ab417ecca0 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/phy.h>
 #include <linux/serial_8250.h>
 #include <linux/stmmac.h>
+#include <linux/usb/ehci_pdriver.h>
 #include <asm-generic/sizes.h>
 
 #include <loongson1.h>
@@ -107,13 +108,18 @@ static struct resource ls1x_ehci_resources[] = {
        },
 };
 
+static struct usb_ehci_pdata ls1x_ehci_pdata = {
+       .port_power_off = 1,
+};
+
 struct platform_device ls1x_ehci_device = {
-       .name           = "ls1x-ehci",
+       .name           = "ehci-platform",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(ls1x_ehci_resources),
        .resource       = ls1x_ehci_resources,
        .dev            = {
                .dma_mask = &ls1x_ehci_dmamask,
+               .platform_data = &ls1x_ehci_pdata,
        },
 };
 
index 71b44d82621db706844aacfb52f698128a6f58b6..507230eeb7685e9292eb533e7932441db11e92e0 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
 #include <linux/i2c.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
 
 #include <asm/netlogic/haldefs.h>
 #include <asm/netlogic/xlr/iomap.h>
@@ -123,12 +125,18 @@ static u64 xls_usb_dmamask = ~(u32)0;
                },                                                      \
        }
 
+static struct usb_ehci_pdata xls_usb_ehci_pdata = {
+       .caps_offset    = 0,
+};
+
+static struct usb_ohci_pdata xls_usb_ohci_pdata;
+
 static struct platform_device xls_usb_ehci_device =
-                        USB_PLATFORM_DEV("ehci-xls", 0, PIC_USB_IRQ);
+                        USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ);
 static struct platform_device xls_usb_ohci_device_0 =
-                        USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ);
+                        USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ);
 static struct platform_device xls_usb_ohci_device_1 =
-                        USB_PLATFORM_DEV("ohci-xls-1", 2, PIC_USB_IRQ);
+                        USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ);
 
 static struct platform_device *xls_platform_devices[] = {
        &xls_usb_ehci_device,
@@ -172,14 +180,17 @@ int xls_platform_usb_init(void)
        memres = CPHYSADDR((unsigned long)usb_mmio);
        xls_usb_ehci_device.resource[0].start = memres;
        xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
+       xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata;
 
        memres += 0x400;
        xls_usb_ohci_device_0.resource[0].start = memres;
        xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
+       xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata;
 
        memres += 0x400;
        xls_usb_ohci_device_1.resource[0].start = memres;
        xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
+       xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata;
 
        return platform_add_devices(xls_platform_devices,
                                ARRAY_SIZE(xls_platform_devices));
index 5264cc09a27bacbe2057ca7a66e50645a3eefd04..0a8faeaa7b70e4c3c9e893dde55e377c31e85f9a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/serial.h>
 #include <linux/serial_pnx8xxx.h>
 #include <linux/platform_device.h>
+#include <linux/usb/ohci_pdriver.h>
 
 #include <int.h>
 #include <usb.h>
@@ -96,12 +97,40 @@ static u64 ohci_dmamask = DMA_BIT_MASK(32);
 
 static u64 uart_dmamask = DMA_BIT_MASK(32);
 
+static int pnx8550_usb_ohci_power_on(struct platform_device *pdev)
+{
+       /*
+        * 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);
+
+       return 0;
+}
+
+static void pnx8550_usb_ohci_power_off(struct platform_device *pdev)
+{
+       udelay(10);
+}
+
+static struct usb_ohci_pdata pnx8550_usb_ohci_pdata = {
+       .power_on       = pnx8550_usb_ohci_power_on,
+       .power_off      = pnx8550_usb_ohci_power_off,
+};
+
 static struct platform_device pnx8550_usb_ohci_device = {
-       .name           = "pnx8550-ohci",
+       .name           = "ohci-platform",
        .id             = -1,
        .dev = {
                .dma_mask               = &ohci_dmamask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &pnx8550_usb_ohci_pdata,
        },
        .num_resources  = ARRAY_SIZE(pnx8550_usb_ohci_resources),
        .resource       = pnx8550_usb_ohci_resources,
index 0c2f1b2c2e1973440465e679ec1dd674e2522836..42d991f632b1f4b013b55af71df2a81f143b6090 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <linux/sh_intc.h>
+#include <linux/usb/ohci_pdriver.h>
 #include <asm/rtc.h>
 #include <cpu/serial.h>
 
@@ -103,12 +104,15 @@ static struct resource usb_ohci_resources[] = {
 
 static u64 usb_ohci_dma_mask = 0xffffffffUL;
 
+static struct usb_ohci_pdata usb_ohci_pdata;
+
 static struct platform_device usb_ohci_device = {
-       .name           = "sh_ohci",
+       .name           = "ohci-platform",
        .id             = -1,
        .dev = {
                .dma_mask               = &usb_ohci_dma_mask,
                .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &usb_ohci_pdata,
        },
        .num_resources  = ARRAY_SIZE(usb_ohci_resources),
        .resource       = usb_ohci_resources,
index 4a2f357f4df8a1b93fd285b0e0c461dbbc2897d5..9079a0f9ea9be7b48369ffd7bcc2e6e516916326 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sh_timer.h>
 #include <linux/sh_dma.h>
 #include <linux/sh_intc.h>
+#include <linux/usb/ohci_pdriver.h>
 #include <cpu/dma-register.h>
 #include <cpu/sh7757.h>
 
@@ -750,12 +751,15 @@ static struct resource usb_ohci_resources[] = {
        },
 };
 
+static struct usb_ohci_pdata usb_ohci_pdata;
+
 static struct platform_device usb_ohci_device = {
-       .name           = "sh_ohci",
+       .name           = "ohci-platform",
        .id             = -1,
        .dev = {
                .dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
                .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data  = &usb_ohci_pdata,
        },
        .num_resources  = ARRAY_SIZE(usb_ohci_resources),
        .resource       = usb_ohci_resources,
index bd0a8fbe610f678077cad20dc1b5af07f9b46b8b..1686acaaf45af226a8f6809f937896abee8000c5 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/sh_intc.h>
 #include <linux/io.h>
 #include <linux/serial_sci.h>
+#include <linux/usb/ohci_pdriver.h>
 
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xffe00000,
@@ -106,12 +107,15 @@ static struct resource usb_ohci_resources[] = {
 
 static u64 usb_ohci_dma_mask = 0xffffffffUL;
 
+static struct usb_ohci_pdata usb_ohci_pdata;
+
 static struct platform_device usb_ohci_device = {
-       .name           = "sh_ohci",
+       .name           = "ohci-platform",
        .id             = -1,
        .dev = {
                .dma_mask               = &usb_ohci_dma_mask,
                .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &usb_ohci_pdata,
        },
        .num_resources  = ARRAY_SIZE(usb_ohci_resources),
        .resource       = usb_ohci_resources,
index 2e6952f87848e287a6ad042414fc8f3d9532ccc8..ab52d4d4484d460bffc3b66ec9be5a60287d92cd 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/sh_timer.h>
 #include <linux/sh_dma.h>
 #include <linux/sh_intc.h>
+#include <linux/usb/ohci_pdriver.h>
 #include <cpu/dma-register.h>
 #include <asm/mmzone.h>
 
@@ -583,12 +584,15 @@ static struct resource usb_ohci_resources[] = {
        },
 };
 
+static struct usb_ohci_pdata usb_ohci_pdata;
+
 static struct platform_device usb_ohci_device = {
-       .name           = "sh_ohci",
+       .name           = "ohci-platform",
        .id             = -1,
        .dev = {
                .dma_mask               = &usb_ohci_device.dev.coherent_dma_mask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &usb_ohci_pdata,
        },
        .num_resources  = ARRAY_SIZE(usb_ohci_resources),
        .resource       = usb_ohci_resources,
index f460de31aceee80200ff9e91f514917bae9f7adc..cbacea933b18cbc9c6287acec62f465495569b1e 100644 (file)
@@ -591,16 +591,14 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
 
        /* Now look at all of this device's children. */
        usb_hub_for_each_child(usbdev, chix, childdev) {
-               if (childdev) {
-                       usb_lock_device(childdev);
-                       ret = usb_device_dump(buffer, nbytes, skip_bytes,
-                                             file_offset, childdev, bus,
-                                             level + 1, chix - 1, ++cnt);
-                       usb_unlock_device(childdev);
-                       if (ret == -EFAULT)
-                               return total_written;
-                       total_written += ret;
-               }
+               usb_lock_device(childdev);
+               ret = usb_device_dump(buffer, nbytes, skip_bytes,
+                                     file_offset, childdev, bus,
+                                     level + 1, chix - 1, ++cnt);
+               usb_unlock_device(childdev);
+               if (ret == -EFAULT)
+                       return total_written;
+               total_written += ret;
        }
        return total_written;
 }
index 1e741bca02652e8f4ed2b027654abc3ac9d16a4f..eaa14514e173163bf46aba9dd65cddaa57fb85fd 100644 (file)
@@ -2039,8 +2039,9 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
        status = hcd->driver->bus_resume(hcd);
        clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
        if (status == 0) {
-               /* TRSMRCY = 10 msec */
-               msleep(10);
+               struct usb_device *udev;
+               int port1;
+
                spin_lock_irq(&hcd_root_hub_lock);
                if (!HCD_DEAD(hcd)) {
                        usb_set_device_state(rhdev, rhdev->actconfig
@@ -2050,6 +2051,20 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
                        hcd->state = HC_STATE_RUNNING;
                }
                spin_unlock_irq(&hcd_root_hub_lock);
+
+               /*
+                * Check whether any of the enabled ports on the root hub are
+                * unsuspended.  If they are then a TRSMRCY delay is needed
+                * (this is what the USB-2 spec calls a "global resume").
+                * Otherwise we can skip the delay.
+                */
+               usb_hub_for_each_child(rhdev, port1, udev) {
+                       if (udev->state != USB_STATE_NOTATTACHED &&
+                                       !udev->port_is_suspended) {
+                               usleep_range(10000, 11000);     /* TRSMRCY */
+                               break;
+                       }
+               }
        } else {
                hcd->state = old_state;
                dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
index 1af04bdeaf0c1884487ed830bcee7dd32ee720b6..5b131b6477db060d37fb9c347736b1aad5a3f415 100644 (file)
@@ -39,6 +39,9 @@
 #endif
 #endif
 
+#define USB_VENDOR_GENESYS_LOGIC               0x05e3
+#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND       0x01
+
 struct usb_port {
        struct usb_device *child;
        struct device dev;
@@ -86,6 +89,8 @@ struct usb_hub {
        unsigned                quiescing:1;
        unsigned                disconnected:1;
 
+       unsigned                quirk_check_port_auto_suspend:1;
+
        unsigned                has_indicators:1;
        u8                      indicator[USB_MAXCHILDREN];
        struct delayed_work     leds;
@@ -1612,6 +1617,41 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
        desc = intf->cur_altsetting;
        hdev = interface_to_usbdev(intf);
 
+       /*
+        * Set default autosuspend delay as 0 to speedup bus suspend,
+        * based on the below considerations:
+        *
+        * - Unlike other drivers, the hub driver does not rely on the
+        *   autosuspend delay to provide enough time to handle a wakeup
+        *   event, and the submitted status URB is just to check future
+        *   change on hub downstream ports, so it is safe to do it.
+        *
+        * - The patch might cause one or more auto supend/resume for
+        *   below very rare devices when they are plugged into hub
+        *   first time:
+        *
+        *      devices having trouble initializing, and disconnect
+        *      themselves from the bus and then reconnect a second
+        *      or so later
+        *
+        *      devices just for downloading firmware, and disconnects
+        *      themselves after completing it
+        *
+        *   For these quite rare devices, their drivers may change the
+        *   autosuspend delay of their parent hub in the probe() to one
+        *   appropriate value to avoid the subtle problem if someone
+        *   does care it.
+        *
+        * - The patch may cause one or more auto suspend/resume on
+        *   hub during running 'lsusb', but it is probably too
+        *   infrequent to worry about.
+        *
+        * - Change autosuspend delay of hub can avoid unnecessary auto
+        *   suspend timer for hub, also may decrease power consumption
+        *   of USB bus.
+        */
+       pm_runtime_set_autosuspend_delay(&hdev->dev, 0);
+
        /* Hubs have proper suspend/resume support. */
        usb_enable_autosuspend(hdev);
 
@@ -1670,6 +1710,9 @@ descriptor_error:
        if (hdev->speed == USB_SPEED_HIGH)
                highspeed_hubs++;
 
+       if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
+               hub->quirk_check_port_auto_suspend = 1;
+
        if (hub_configure(hub, endpoint) >= 0)
                return 0;
 
@@ -2879,6 +2922,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
                                (PMSG_IS_AUTO(msg) ? "auto-" : ""),
                                udev->do_remote_wakeup);
                usb_set_device_state(udev, USB_STATE_SUSPENDED);
+               udev->port_is_suspended = 1;
                msleep(10);
        }
        usb_mark_last_busy(hub->hdev);
@@ -3043,6 +3087,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
 
  SuspendCleared:
        if (status == 0) {
+               udev->port_is_suspended = 0;
                if (hub_is_superspeed(hub->hdev)) {
                        if (portchange & USB_PORT_STAT_C_LINK_STATE)
                                clear_port_feature(hub->hdev, port1,
@@ -3126,6 +3171,21 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
 
 #endif
 
+static int check_ports_changed(struct usb_hub *hub)
+{
+       int port1;
+
+       for (port1 = 1; port1 <= hub->hdev->maxchild; ++port1) {
+               u16 portstatus, portchange;
+               int status;
+
+               status = hub_port_status(hub, port1, &portstatus, &portchange);
+               if (!status && portchange)
+                       return 1;
+       }
+       return 0;
+}
+
 static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 {
        struct usb_hub          *hub = usb_get_intfdata (intf);
@@ -3144,6 +3204,16 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
                                return -EBUSY;
                }
        }
+
+       if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) {
+               /* check if there are changes pending on hub ports */
+               if (check_ports_changed(hub)) {
+                       if (PMSG_IS_AUTO(msg))
+                               return -EBUSY;
+                       pm_wakeup_event(&hdev->dev, 2000);
+               }
+       }
+
        if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) {
                /* Enable hub to send remote wakeup for all ports. */
                for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -4648,6 +4718,11 @@ static int hub_thread(void *__unused)
 }
 
 static const struct usb_device_id hub_id_table[] = {
+    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+                  | USB_DEVICE_ID_MATCH_INT_CLASS,
+      .idVendor = USB_VENDOR_GENESYS_LOGIC,
+      .bInterfaceClass = USB_CLASS_HUB,
+      .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},
     { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
       .bDeviceClass = USB_CLASS_HUB},
     { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
index 9d912bfdcffe0e5a47f58c685688e0bcf31547bf..3662287e2f4feadd4876fad2d37072f70c065fce 100644 (file)
@@ -214,9 +214,25 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
  * urb->interval is modified to reflect the actual transfer period used
  * (normally some power of two units).  And for isochronous urbs,
  * urb->start_frame is modified to reflect when the URB's transfers were
- * scheduled to start.  Not all isochronous transfer scheduling policies
- * will work, but most host controller drivers should easily handle ISO
- * queues going from now until 10-200 msec into the future.
+ * scheduled to start.
+ *
+ * Not all isochronous transfer scheduling policies will work, but most
+ * host controller drivers should easily handle ISO queues going from now
+ * until 10-200 msec into the future.  Drivers should try to keep at
+ * least one or two msec of data in the queue; many controllers require
+ * that new transfers start at least 1 msec in the future when they are
+ * added.  If the driver is unable to keep up and the queue empties out,
+ * the behavior for new submissions is governed by the URB_ISO_ASAP flag.
+ * If the flag is set, or if the queue is idle, then the URB is always
+ * assigned to the first available (and not yet expired) slot in the
+ * endpoint's schedule.  If the flag is not set and the queue is active
+ * then the URB is always assigned to the next slot in the schedule
+ * following the end of the endpoint's previous URB, even if that slot is
+ * in the past.  When a packet is assigned in this way to a slot that has
+ * already expired, the packet is not transmitted and the corresponding
+ * usb_iso_packet_descriptor's status field will return -EXDEV.  If this
+ * would happen to all the packets in the URB, submission fails with a
+ * -EXDEV error code.
  *
  * For control endpoints, the synchronous usb_control_msg() call is
  * often used (in non-interrupt context) instead of this call.
index cd8fb44a3e164030ffe59a38a0af0baa42371051..7d3de09a82e4ae70a51173dbacbb7fe81e07fadb 100644 (file)
@@ -370,14 +370,14 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
                                 struct usb_bus *bus, unsigned port1)
 {
        struct usb_device *dev;
-       struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self);
+       struct usb_hcd *usb_hcd = bus_to_hcd(bus);
        unsigned root_hub = 0;
 
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev)
                return NULL;
 
-       if (!usb_get_hcd(bus_to_hcd(bus))) {
+       if (!usb_get_hcd(usb_hcd)) {
                kfree(dev);
                return NULL;
        }
index 3f1431d37e1c836f88b32aff5b002fb9cf4efa0b..8cc06f054c6a3bfa32ebf1ee0af333849feb1b05 100644 (file)
@@ -215,9 +215,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 +337,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 +387,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 +404,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.
 
index 9e0a89ced15cb3aa6d699aabd5be7a34df9e53c0..332ed897a6fbd4706d8101d5f013fe67c0e48b03 100644 (file)
@@ -40,6 +40,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 (file)
index 936af83..0000000
+++ /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/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
deleted file mode 100644 (file)
index 65c945e..0000000
+++ /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 (file)
index d91708d..0000000
+++ /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",
-       },
-};
index 1599806e3d47cddd7de228a4bb779b2a5e11fdd9..dfd3bf3aa4de2c35b965c32e792a44dfaf7c7ea8 100644 (file)
 
 /* 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
index 6bf6c42481e8a6c645236ab27c170819c6f76024..9c2afb516fe5b37e372a97d3f6c01bdc140b78cc 100644 (file)
@@ -118,9 +118,34 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
 /*-------------------------------------------------------------------------*/
 
 #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"
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -503,7 +528,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);
 
@@ -1219,11 +1244,6 @@ MODULE_LICENSE ("GPL");
 #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 +1269,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 +1284,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,21 +1324,11 @@ 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
index 914ce9370e70f4a1d9a956ccf50fae9b97973b21..a7ec827ca2ca697344418a58a9dc3d0c27aae316 100644 (file)
@@ -384,11 +384,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;
 
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c
deleted file mode 100644 (file)
index f224c0a..0000000
+++ /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",
-       },
-};
index 2111627a19deefa935d4e724efe86965893dc168..6b092c1dff64c4e78035899304896296e82263e4 100644 (file)
@@ -17,8 +17,8 @@
 */
 
 /* 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)
+
+static int ehci_lpm_set_da(struct ehci_hcd *ehci, int dev_addr, int port_num)
 {
        u32 __iomem portsc;
 
@@ -38,7 +38,7 @@ static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci,
  * 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)
+static int ehci_lpm_check(struct ehci_hcd *ehci, int port)
 {
        u32 __iomem     *portsc ;
        u32 val32;
@@ -82,3 +82,20 @@ static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port)
 
        return retval;
 }
+
+static int __maybe_unused 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;
+}
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c
deleted file mode 100644 (file)
index ca75965..0000000
+++ /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");
index 2cb7d370c4eff93ee39509f739e9669ff2cd3a0a..7880ba621f89552ee0d76fc4ae5b70a75d256d23 100644 (file)
@@ -103,7 +103,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;
@@ -380,22 +379,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
 }
 #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;
-}
-
 static const struct hc_driver ehci_pci_hc_driver = {
        .description =          hcd_name,
        .product_desc =         "EHCI Host Controller",
index 764e0100b6f438d82ab64057e8cb37abd638fa79..272728c48c9e6e2aa6b4cf7604a8d9280e195b0c 100644 (file)
@@ -38,6 +38,8 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
        if (retval)
                return retval;
 
+       if (pdata->no_io_watchdog)
+               ehci->need_io_watchdog = 0;
        if (pdata->port_power_on)
                ehci_port_power(ehci, 1);
        if (pdata->port_power_off)
@@ -96,12 +98,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 +123,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:
@@ -159,8 +151,6 @@ static int __devexit ehci_platform_remove(struct platform_device *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);
 
index 85b74be202eb3b25a2c75dbde9386805dd9d6f79..abc178d21fe49fd3bbd504a913c7bae529f2d092 100644 (file)
@@ -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,7 +183,7 @@ 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;
@@ -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);
index 7cf3da7babf0009b6732302ecef280cc01429ff6..2e14714b359fa6b123f133af5d7133393c205895 100644 (file)
 
 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:
@@ -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++;
                }
        }
 
@@ -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;
 }
index 6223d1757848c6d43db7aa59d7042b1c8c736f02..2de089001ae98890c0cf70a74c647ece79582606 100644 (file)
 #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
 
index d3c9a3e397b99ed4f423ee41575038890ff4e4eb..c6fe0bb619cb212499ba2b04b0c64c1f396d5da2 100644 (file)
 #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",
index ec598082c14b09476f7de3369f75b0d04b3a6a69..fdd7c4873cf20361aed91c58910828eff9cdebf0 100644 (file)
@@ -13,7 +13,7 @@
 
 #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)
diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c
deleted file mode 100644 (file)
index 8dc6a22..0000000
+++ /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",
-       },
-};
index da07d98f7d1de7780c578853e92b705c1231d316..ec948c3b1cea6faba93862fc33fe3c6f5234d800 100644 (file)
@@ -143,7 +143,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 +193,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) */
@@ -762,22 +761,21 @@ 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 */
index fff114fd546155382d092b883547a12bca306ce2..958379f9de79596ad5fa5b5d179dbde0042ad7c4 100644 (file)
@@ -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;
 
index 0bf72f943b00d392654fdc9613e4f397bfac2d32..908d84af1dd72bca08b80f40177dfdecc881bd00 100644 (file)
@@ -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
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
deleted file mode 100644 (file)
index c611699..0000000
+++ /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 (file)
index 2c9f233..0000000
+++ /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",
-       },
-};
index dbfbd1dfd2e2f798aae4fc60456d2190e47d0428..a982f04ed78705b037af6e91037ebea20a84ab85 100644 (file)
@@ -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
index 20a50081f9225d7111c7a9ddfe3d91dc1f8bde97..2f303295b428b0f10f867aaea5ac2daee4583e5e 100644 (file)
@@ -115,7 +115,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 +123,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,9 +167,7 @@ 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;
@@ -186,8 +184,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 +229,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 +244,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;
 }
index 4a1d64d92338e7653035b054decf6e714909a41f..180a2b01db56c9d496fb52388a324d2df2b4a931 100644 (file)
@@ -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
index 2f3619eefefa9bca87189e5da44dd6bbb0cd8191..db09dae7b557a18063d424a3ffc58c1edb8ccca8 100644 (file)
@@ -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)
index 4531d03503c32371f4b1c5cd505ac38243dafe13..733c77c36355ac95082ec08cc3ceb4e3c7d9d881 100644 (file)
@@ -530,7 +530,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;
 }
 
index 1843bb68ac7ceefc73afcc2ed9f3a2f7fa8de1db..6afa7dc4e4c39a3f4ec5374915819b8483e74a9f 100644 (file)
@@ -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
 
        /*
index e24ec9f79164afc9e6563a147cb76d4c0f3c96c3..bda4e0bb8ab3c14a0b4e02e8e40b2bd2b9306359 100644 (file)
@@ -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;
@@ -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:
@@ -161,8 +155,6 @@ static int __devexit ohci_platform_remove(struct platform_device *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;
 }
 
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c
deleted file mode 100644 (file)
index 148d27d..0000000
+++ /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-soc.c b/drivers/usb/host/ohci-ppc-soc.c
deleted file mode 100644 (file)
index 185c39e..0000000
+++ /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");
index 2bf11440b010443290f2cbd6795cf22ddf561b0d..156d289d3bb51112b6aad220291101ceafe5e4ff 100644 (file)
@@ -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;
 }
 
index c5a1ea9145faec6e65809ddf1fdbb7046f6897cc..177a213790d47f6d9abe059c15e8043230f690c8 100644 (file)
@@ -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
index 0d2309ca471eeb9fff1be06da36081f4878bd42c..e84190f25c6b7b6995d32f53d7e1818f1f6608bc 100644 (file)
@@ -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);
@@ -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;
 }
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c
deleted file mode 100644 (file)
index 76a20c2..0000000
+++ /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");
index 5596ac2ba1ca55851c21b1f3044d0bfef0e17085..3b5b908fd47b29e25f0f90198c85607182152fef 100644 (file)
@@ -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
index fc7305ee3c9cd465ecdb68c64b140e9f9da10fc9..d607be33c03c865a6a6abcd5245deee02e8b3a03 100644 (file)
@@ -231,7 +231,7 @@ 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
index 60c2b0722f2e16280f32db0ada071260e9ef30d4..2c9ab8f126d456df6ce02e7cccd771e651b4b3e6 100644 (file)
@@ -352,7 +352,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;
 }
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c
deleted file mode 100644 (file)
index 84201cd..0000000
+++ /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,
-       },
-};
index fcc09e5ec0addc9cd9661086b1e18165bd5f8ba4..b3eea0ba97a936b9743245971d0a94a1e6b2e45e 100644 (file)
@@ -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 */
index d2c6f5ac4626af6c0297ab1348b9a14b18f77605..15921fd55048614de4940dabbdfb95564a129392 100644 (file)
@@ -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);
index 6589268a651517da44f99cd7391e2ca35f84f12a..e712afed947c0743dffa1a099ca91832288eeb89 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/usb.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
+#include <linux/usb/ezusb.h>
 
 struct ezusb_fx_type {
        /* EZ-USB Control and Status Register.  Bit 0 controls 8051 reset */
@@ -22,21 +23,16 @@ struct ezusb_fx_type {
        unsigned short max_internal_adress;
 };
 
-struct ezusb_fx_type ezusb_fx1 = {
+static struct ezusb_fx_type ezusb_fx1 = {
        .cpucs_reg = 0x7F92,
        .max_internal_adress = 0x1B3F,
 };
 
-struct ezusb_fx_type ezusb_fx2 = {
-       .cpucs_reg = 0xE600,
-       .max_internal_adress = 0x3FFF,
-};
-
 /* Commands for writing to memory */
 #define WRITE_INT_RAM 0xA0
 #define WRITE_EXT_RAM 0xA3
 
-int ezusb_writememory(struct usb_device *dev, int address,
+static int ezusb_writememory(struct usb_device *dev, int address,
                                unsigned char *data, int length, __u8 request)
 {
        int result;
@@ -58,10 +54,9 @@ int ezusb_writememory(struct usb_device *dev, int address,
        kfree(transfer_buffer);
        return result;
 }
-EXPORT_SYMBOL_GPL(ezusb_writememory);
 
-int ezusb_set_reset(struct usb_device *dev, unsigned short cpucs_reg,
-                        unsigned char reset_bit)
+static int ezusb_set_reset(struct usb_device *dev, unsigned short cpucs_reg,
+                          unsigned char reset_bit)
 {
        int response = ezusb_writememory(dev, cpucs_reg, &reset_bit, 1, WRITE_INT_RAM);
        if (response < 0)
@@ -76,12 +71,6 @@ int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit)
 }
 EXPORT_SYMBOL_GPL(ezusb_fx1_set_reset);
 
-int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit)
-{
-       return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit);
-}
-EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset);
-
 static int ezusb_ihex_firmware_download(struct usb_device *dev,
                                        struct ezusb_fx_type fx,
                                        const char *firmware_path)
@@ -151,11 +140,28 @@ int ezusb_fx1_ihex_firmware_download(struct usb_device *dev,
 }
 EXPORT_SYMBOL_GPL(ezusb_fx1_ihex_firmware_download);
 
+#if 0
+/*
+ * Once someone one needs these fx2 functions, uncomment them
+ * and add them to ezusb.h and all should be good.
+ */
+static struct ezusb_fx_type ezusb_fx2 = {
+       .cpucs_reg = 0xE600,
+       .max_internal_adress = 0x3FFF,
+};
+
+int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit)
+{
+       return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit);
+}
+EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset);
+
 int ezusb_fx2_ihex_firmware_download(struct usb_device *dev,
                                     const char *firmware_path)
 {
        return ezusb_ihex_firmware_download(dev, ezusb_fx2, firmware_path);
 }
 EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download);
+#endif
 
 MODULE_LICENSE("GPL");
index 987116f9efcdec0fc7693725f3d315850f5f9eb8..9d13c81754e0cd0d2b38299dcb6143847ad380b2 100644 (file)
@@ -29,7 +29,9 @@
 #include <linux/usb/ulpi.h>
 #include <asm/mach-types.h>
 #include <linux/usb/tegra_usb_phy.h>
-#include <mach/iomap.h>
+
+#define TEGRA_USB_BASE         0xC5000000
+#define TEGRA_USB_SIZE         SZ_16K
 
 #define ULPI_VIEWPORT          0x170
 
index be845873e23dba98fc306fecceb71a672a2c7d74..38151557223561905708066b4a3f42786d8b6151 100644 (file)
@@ -923,6 +923,7 @@ static int ftdi_get_icount(struct tty_struct *tty,
 static int  ftdi_ioctl(struct tty_struct *tty,
                        unsigned int cmd, unsigned long arg);
 static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
+static int ftdi_chars_in_buffer(struct tty_struct *tty);
 
 static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
 static unsigned short int ftdi_232am_baud_to_divisor(int baud);
@@ -957,6 +958,7 @@ static struct usb_serial_driver ftdi_sio_device = {
        .ioctl =                ftdi_ioctl,
        .set_termios =          ftdi_set_termios,
        .break_ctl =            ftdi_break_ctl,
+       .chars_in_buffer =      ftdi_chars_in_buffer,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -2089,6 +2091,64 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
 
 }
 
+static int ftdi_chars_in_buffer(struct tty_struct *tty)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct ftdi_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       int chars;
+       unsigned char *buf;
+       int ret;
+
+       /* Check software buffer (code from
+        * usb_serial_generic_chars_in_buffer()) */
+       spin_lock_irqsave(&port->lock, flags);
+       chars = kfifo_len(&port->write_fifo) + port->tx_bytes;
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       /* Check hardware buffer */
+       switch (priv->chip_type) {
+       case FT8U232AM:
+       case FT232BM:
+       case FT2232C:
+       case FT232RL:
+       case FT2232H:
+       case FT4232H:
+       case FT232H:
+       case FTX:
+               break;
+       case SIO:
+       default:
+               return chars;
+       }
+
+       buf = kmalloc(2, GFP_KERNEL);
+       if (!buf) {
+               dev_err(&port->dev, "kmalloc failed");
+               return chars;
+       }
+
+       ret = usb_control_msg(port->serial->dev,
+                               usb_rcvctrlpipe(port->serial->dev, 0),
+                               FTDI_SIO_GET_MODEM_STATUS_REQUEST,
+                               FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+                               0, priv->interface,
+                               buf, 2, WDR_TIMEOUT);
+
+       if (ret < 2) {
+               dev_err(&port->dev, "Unable to read modem and line status: "
+                       "%i\n", ret);
+               goto chars_in_buffer_out;
+       }
+
+       if (!(buf[1] & FTDI_RS_TEMT))
+               chars++;
+
+chars_in_buffer_out:
+       kfree(buf);
+       return chars;
+}
+
 /* old_termios contains the original termios settings and tty->termios contains
  * the new setting to be used
  * WARNING: set_termios calls this with old_termios in kernel space
index 0616f235bd6b512ecf54769cfc346e12180febd7..ce310170829fdc66442a8c7b629fc028152c96af 100644 (file)
@@ -105,20 +105,15 @@ static int skel_open(struct inode *inode, struct file *file)
                goto exit;
        }
 
-       /* increment our usage count for the device */
-       kref_get(&dev->kref);
-
-       /* lock the device to allow correctly handling errors
-        * in resumption */
-       mutex_lock(&dev->io_mutex);
-
        retval = usb_autopm_get_interface(interface);
        if (retval)
-               goto out_err;
+               goto exit;
+
+       /* increment our usage count for the device */
+       kref_get(&dev->kref);
 
        /* save our object in the file's private structure */
        file->private_data = dev;
-       mutex_unlock(&dev->io_mutex);
 
 exit:
        return retval;
index 231009af65a3a05712dfd34d8484a7b0a02da18e..1d365316960cdad1a0a020d6d2757a0e5f73f85e 100644 (file)
@@ -847,19 +847,6 @@ static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev)
        wusb_dev->wusb_cap_descr = NULL;
 };
 
-static struct usb_wireless_cap_descriptor wusb_cap_descr_default = {
-       .bLength = sizeof(wusb_cap_descr_default),
-       .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
-       .bDevCapabilityType = USB_CAP_TYPE_WIRELESS_USB,
-
-       .bmAttributes = USB_WIRELESS_BEACON_NONE,
-       .wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53),
-       .bmTFITXPowerInfo = 0,
-       .bmFFITXPowerInfo = 0,
-       .bmBandGroup = cpu_to_le16(0x0001),     /* WUSB1.0[7.4.1] bottom */
-       .bReserved = 0
-};
-
 /*
  * USB stack's device addition Notifier Callback
  *
index 82a84d53120f27f2a1734fcef5ab5774d5fbc0a3..5c5b3fc9088a30d25fd526fca9427006e9f9d23e 100644 (file)
@@ -63,7 +63,7 @@ int umc_controller_reset(struct umc_dev *umc)
        struct device *parent = umc->dev.parent;
        int ret = 0;
 
-       if (device_trylock(parent))
+       if (!device_trylock(parent))
                return -EAGAIN;
        ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
        if (ret >= 0)
index 10278d18709cf439d3fc2aeea2b7057f22eee16a..f51f9981de1ed9157257f63fff244e4397c71fe1 100644 (file)
@@ -482,6 +482,7 @@ struct usb3_lpm_parameters {
  * @connect_time: time device was first connected
  * @do_remote_wakeup:  remote wakeup should be enabled
  * @reset_resume: needs reset instead of resume
+ * @port_is_suspended: the upstream port is suspended (L2 or U3)
  * @wusb_dev: if this is a Wireless USB device, link to the WUSB
  *     specific data for the device.
  * @slot_id: Slot ID assigned by xHCI
@@ -560,6 +561,7 @@ struct usb_device {
 
        unsigned do_remote_wakeup:1;
        unsigned reset_resume:1;
+       unsigned port_is_suspended:1;
 #endif
        struct wusb_dev *wusb_dev;
        int slot_id;
@@ -588,8 +590,9 @@ extern struct usb_device *usb_hub_find_child(struct usb_device *hdev,
  */
 #define usb_hub_for_each_child(hdev, port1, child) \
        for (port1 = 1, child = usb_hub_find_child(hdev, port1); \
-               port1 <= hdev->maxchild; \
-               child = usb_hub_find_child(hdev, ++port1))
+                       port1 <= hdev->maxchild; \
+                       child = usb_hub_find_child(hdev, ++port1)) \
+               if (!child) continue; else
 
 /* USB device locking */
 #define usb_lock_device(udev)          device_lock(&(udev)->dev)
@@ -1129,8 +1132,8 @@ extern int usb_disabled(void);
  * Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb().
  */
 #define URB_SHORT_NOT_OK       0x0001  /* report short reads as errors */
-#define URB_ISO_ASAP           0x0002  /* iso-only, urb->start_frame
-                                        * ignored */
+#define URB_ISO_ASAP           0x0002  /* iso-only; use the first unexpired
+                                        * slot in the schedule */
 #define URB_NO_TRANSFER_DMA_MAP        0x0004  /* urb->transfer_dma valid on submit */
 #define URB_NO_FSBR            0x0020  /* UHCI-specific */
 #define URB_ZERO_PACKET                0x0040  /* Finish bulk OUT with short packet */
@@ -1309,15 +1312,20 @@ typedef void (*usb_complete_t)(struct urb *);
  * the transfer interval in the endpoint descriptor is logarithmic.
  * Device drivers must convert that value to linear units themselves.)
  *
- * Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling
- * the host controller to schedule the transfer as soon as bandwidth
- * utilization allows, and then set start_frame to reflect the actual frame
- * selected during submission.  Otherwise drivers must specify the start_frame
- * and handle the case where the transfer can't begin then.  However, drivers
- * won't know how bandwidth is currently allocated, and while they can
- * find the current frame using usb_get_current_frame_number () they can't
- * know the range for that frame number.  (Ranges for frame counter values
- * are HC-specific, and can go from 256 to 65536 frames from "now".)
+ * If an isochronous endpoint queue isn't already running, the host
+ * controller will schedule a new URB to start as soon as bandwidth
+ * utilization allows.  If the queue is running then a new URB will be
+ * scheduled to start in the first transfer slot following the end of the
+ * preceding URB, if that slot has not already expired.  If the slot has
+ * expired (which can happen when IRQ delivery is delayed for a long time),
+ * the scheduling behavior depends on the URB_ISO_ASAP flag.  If the flag
+ * is clear then the URB will be scheduled to start in the expired slot,
+ * implying that some of its packets will not be transferred; if the flag
+ * is set then the URB will be scheduled in the first unexpired slot,
+ * breaking the queue's synchronization.  Upon URB completion, the
+ * start_frame field will be set to the (micro)frame number in which the
+ * transfer was scheduled.  Ranges for frame counter values are HC-specific
+ * and can go from as low as 256 to as high as 65536 frames.
  *
  * Isochronous URBs have a different data transfer model, in part because
  * the quality of service is only "best effort".  Callers provide specially
index c9d09f8b7ff2d66579ee58700658667347ef8094..67ac74bde6d0d533bb36e12697e424ddfb69e2b6 100644 (file)
@@ -29,6 +29,8 @@
  *                     initialization.
  * @port_power_off:    set to 1 if the controller needs to be powered down
  *                     after initialization.
+ * @no_io_watchdog:    set to 1 if the controller does not need the I/O
+ *                     watchdog to run.
  *
  * These are general configuration options for the EHCI controller. All of
  * these options are activating more or less workarounds for some hardware.
@@ -41,6 +43,7 @@ struct usb_ehci_pdata {
        unsigned        big_endian_mmio:1;
        unsigned        port_power_on:1;
        unsigned        port_power_off:1;
+       unsigned        no_io_watchdog:1;
 
        /* Turn on all power and clocks */
        int (*power_on)(struct platform_device *pdev);
index fc618d8d1e92e845b00f800b86d64a9c2c040408..639ee45779fb381edb59a0ae70e1d5ffe0f90f7f 100644 (file)
@@ -1,16 +1,8 @@
 #ifndef __EZUSB_H
 #define __EZUSB_H
 
-
-extern int ezusb_writememory(struct usb_device *dev, int address,
-                            unsigned char *data, int length, __u8 bRequest);
-
 extern int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit);
-extern int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit);
-
 extern int ezusb_fx1_ihex_firmware_download(struct usb_device *dev,
                                            const char *firmware_path);
-extern int ezusb_fx2_ihex_firmware_download(struct usb_device *dev,
-                                           const char *firmware_path);
 
 #endif /* __EZUSB_H */
index 74e7755168b72c3efed2c39e46a39d7eefc5f858..012f2b7eb2b6b299e21596a9e650487759815dfb 100644 (file)
@@ -25,6 +25,7 @@
  * @big_endian_desc:   BE descriptors
  * @big_endian_mmio:   BE registers
  * @no_big_frame_no:   no big endian frame_no shift
+ * @num_ports:         number of ports
  *
  * These are general configuration options for the OHCI controller. All of
  * these options are activating more or less workarounds for some hardware.
@@ -33,6 +34,7 @@ struct usb_ohci_pdata {
        unsigned        big_endian_desc:1;
        unsigned        big_endian_mmio:1;
        unsigned        no_big_frame_no:1;
+       unsigned int    num_ports;
 
        /* Turn on all power and clocks */
        int (*power_on)(struct platform_device *pdev);