summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/devices.c18
-rw-r--r--drivers/usb/core/hcd.c19
-rw-r--r--drivers/usb/core/hub.c75
-rw-r--r--drivers/usb/core/urb.c22
-rw-r--r--drivers/usb/core/usb.c4
-rw-r--r--drivers/usb/host/Kconfig28
-rw-r--r--drivers/usb/host/Makefile1
-rw-r--r--drivers/usb/host/alchemy-common.c614
-rw-r--r--drivers/usb/host/ehci-au1xxx.c184
-rw-r--r--drivers/usb/host/ehci-cns3xxx.c155
-rw-r--r--drivers/usb/host/ehci-dbg.c15
-rw-r--r--drivers/usb/host/ehci-hcd.c54
-rw-r--r--drivers/usb/host/ehci-hub.c23
-rw-r--r--drivers/usb/host/ehci-ixp4xx.c139
-rw-r--r--drivers/usb/host/ehci-lpm.c23
-rw-r--r--drivers/usb/host/ehci-ls1x.c147
-rw-r--r--drivers/usb/host/ehci-pci.c17
-rw-r--r--drivers/usb/host/ehci-platform.c24
-rw-r--r--drivers/usb/host/ehci-s5p.c10
-rw-r--r--drivers/usb/host/ehci-sched.c132
-rw-r--r--drivers/usb/host/ehci-tegra.c5
-rw-r--r--drivers/usb/host/ehci-vt8500.c16
-rw-r--r--drivers/usb/host/ehci-w90x900.c2
-rw-r--r--drivers/usb/host/ehci-xls.c142
-rw-r--r--drivers/usb/host/ehci.h28
-rw-r--r--drivers/usb/host/isp1760-if.c7
-rw-r--r--drivers/usb/host/ohci-at91.c2
-rw-r--r--drivers/usb/host/ohci-au1xxx.c234
-rw-r--r--drivers/usb/host/ohci-cns3xxx.c166
-rw-r--r--drivers/usb/host/ohci-ep93xx.c2
-rw-r--r--drivers/usb/host/ohci-exynos.c22
-rw-r--r--drivers/usb/host/ohci-hcd.c139
-rw-r--r--drivers/usb/host/ohci-hub.c42
-rw-r--r--drivers/usb/host/ohci-omap.c2
-rw-r--r--drivers/usb/host/ohci-pci.c47
-rw-r--r--drivers/usb/host/ohci-platform.c28
-rw-r--r--drivers/usb/host/ohci-pnx8550.c243
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c216
-rw-r--r--drivers/usb/host/ohci-pxa27x.c2
-rw-r--r--drivers/usb/host/ohci-q.c4
-rw-r--r--drivers/usb/host/ohci-s3c2410.c35
-rw-r--r--drivers/usb/host/ohci-sh.c141
-rw-r--r--drivers/usb/host/ohci-sm501.c2
-rw-r--r--drivers/usb/host/ohci-spear.c2
-rw-r--r--drivers/usb/host/ohci-tmio.c2
-rw-r--r--drivers/usb/host/ohci-xls.c152
-rw-r--r--drivers/usb/host/r8a66597-hcd.c6
-rw-r--r--drivers/usb/host/uhci-q.c73
-rw-r--r--drivers/usb/misc/ezusb.c38
-rw-r--r--drivers/usb/phy/tegra_usb_phy.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c60
-rw-r--r--drivers/usb/usb-skeleton.c13
-rw-r--r--drivers/usb/wusbcore/devconnect.c13
53 files changed, 562 insertions, 3032 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index f460de31acee..cbacea933b18 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -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;
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 1e741bca0265..eaa14514e173 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -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",
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1af04bdeaf0c..5b131b6477db 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -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,
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 9d912bfdcffe..3662287e2f4f 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -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.
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index cd8fb44a3e16..7d3de09a82e4 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -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;
}
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3f1431d37e1c..8cc06f054c6a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -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.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9e0a89ced15c..332ed897a6fb 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -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
index 936af8359fb2..000000000000
--- a/drivers/usb/host/alchemy-common.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * USB block power/access management abstraction.
- *
- * Au1000+: The OHCI block control register is at the far end of the OHCI memory
- * area. Au1550 has OHCI on different base address. No need to handle
- * UDC here.
- * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG
- * as well as the PHY for EHCI and UDC.
- *
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/syscore_ops.h>
-#include <asm/mach-au1x00/au1000.h>
-
-/* control register offsets */
-#define AU1000_OHCICFG 0x7fffc
-#define AU1550_OHCICFG 0x07ffc
-#define AU1200_USBCFG 0x04
-
-/* Au1000 USB block config bits */
-#define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */
-#define USBHEN_CE (1 << 3) /* OHCI block clock enable */
-#define USBHEN_E (1 << 2) /* OHCI block enable */
-#define USBHEN_C (1 << 1) /* OHCI block coherency bit */
-#define USBHEN_BE (1 << 0) /* OHCI Big-Endian */
-
-/* Au1200 USB config bits */
-#define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */
-#define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */
-#define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */
-#define USBCFG_SSD (1 << 23) /* serial short detect en */
-#define USBCFG_PPE (1 << 19) /* HS PHY PLL */
-#define USBCFG_UCE (1 << 18) /* UDC clock enable */
-#define USBCFG_ECE (1 << 17) /* EHCI clock enable */
-#define USBCFG_OCE (1 << 16) /* OHCI clock enable */
-#define USBCFG_FLA(x) (((x) & 0x3f) << 8)
-#define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */
-#define USBCFG_GME (1 << 6) /* OTG mem access */
-#define USBCFG_DBE (1 << 5) /* UDC busmaster enable */
-#define USBCFG_DME (1 << 4) /* UDC mem enable */
-#define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */
-#define USBCFG_EME (1 << 2) /* EHCI mem enable */
-#define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */
-#define USBCFG_OME (1 << 0) /* OHCI mem enable */
-#define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\
- USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \
- USBCFG_GME | USBCFG_DBE | USBCFG_DME | \
- USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \
- USBCFG_OME)
-
-/* Au1300 USB config registers */
-#define USB_DWC_CTRL1 0x00
-#define USB_DWC_CTRL2 0x04
-#define USB_VBUS_TIMER 0x10
-#define USB_SBUS_CTRL 0x14
-#define USB_MSR_ERR 0x18
-#define USB_DWC_CTRL3 0x1C
-#define USB_DWC_CTRL4 0x20
-#define USB_OTG_STATUS 0x28
-#define USB_DWC_CTRL5 0x2C
-#define USB_DWC_CTRL6 0x30
-#define USB_DWC_CTRL7 0x34
-#define USB_PHY_STATUS 0xC0
-#define USB_INT_STATUS 0xC4
-#define USB_INT_ENABLE 0xC8
-
-#define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */
-#define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */
-#define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */
-
-#define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */
-#define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */
-#define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */
-
-#define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19)
-#define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18)
-#define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17)
-#define USB_DWC_CTRL3_OTG0_CKEN (1 << 16)
-
-#define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */
-
-#define USB_INTEN_FORCE 0x20
-#define USB_INTEN_PHY 0x10
-#define USB_INTEN_UDC 0x08
-#define USB_INTEN_EHCI 0x04
-#define USB_INTEN_OHCI1 0x02
-#define USB_INTEN_OHCI0 0x01
-
-static DEFINE_SPINLOCK(alchemy_usb_lock);
-
-static inline void __au1300_usb_phyctl(void __iomem *base, int enable)
-{
- unsigned long r, s;
-
- r = __raw_readl(base + USB_DWC_CTRL2);
- s = __raw_readl(base + USB_DWC_CTRL3);
-
- s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN |
- USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN;
-
- if (enable) {
- /* simply enable all PHYs */
- r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
- USB_DWC_CTRL2_PHYRS;
- __raw_writel(r, base + USB_DWC_CTRL2);
- wmb();
- } else if (!s) {
- /* no USB block active, do disable all PHYs */
- r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
- USB_DWC_CTRL2_PHYRS);
- __raw_writel(r, base + USB_DWC_CTRL2);
- wmb();
- }
-}
-
-static inline void __au1300_ohci_control(void __iomem *base, int enable, int id)
-{
- unsigned long r;
-
- if (enable) {
- __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */
- r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
- : USB_DWC_CTRL3_OHCI1_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable); /* power up the PHYs */
-
- r = __raw_readl(base + USB_INT_ENABLE);
- r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- /* reset the OHCI start clock bit */
- __raw_writel(0, base + USB_DWC_CTRL7);
- wmb();
- } else {
- r = __raw_readl(base + USB_INT_ENABLE);
- r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1);
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3);
- r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
- : USB_DWC_CTRL3_OHCI1_CKEN);
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline void __au1300_ehci_control(void __iomem *base, int enable)
-{
- unsigned long r;
-
- if (enable) {
- r = __raw_readl(base + USB_DWC_CTRL3);
- r |= USB_DWC_CTRL3_EHCI0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r |= USB_DWC_CTRL1_HSTRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
-
- r = __raw_readl(base + USB_INT_ENABLE);
- r |= USB_INTEN_EHCI;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
- } else {
- r = __raw_readl(base + USB_INT_ENABLE);
- r &= ~USB_INTEN_EHCI;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r &= ~USB_DWC_CTRL1_HSTRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3);
- r &= ~USB_DWC_CTRL3_EHCI0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline void __au1300_udc_control(void __iomem *base, int enable)
-{
- unsigned long r;
-
- if (enable) {
- r = __raw_readl(base + USB_DWC_CTRL1);
- r |= USB_DWC_CTRL1_DCRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
-
- r = __raw_readl(base + USB_INT_ENABLE);
- r |= USB_INTEN_UDC;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
- } else {
- r = __raw_readl(base + USB_INT_ENABLE);
- r &= ~USB_INTEN_UDC;
- __raw_writel(r, base + USB_INT_ENABLE);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r &= ~USB_DWC_CTRL1_DCRS;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline void __au1300_otg_control(void __iomem *base, int enable)
-{
- unsigned long r;
- if (enable) {
- r = __raw_readl(base + USB_DWC_CTRL3);
- r |= USB_DWC_CTRL3_OTG0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL1);
- r &= ~USB_DWC_CTRL1_OTGD;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- } else {
- r = __raw_readl(base + USB_DWC_CTRL1);
- r |= USB_DWC_CTRL1_OTGD;
- __raw_writel(r, base + USB_DWC_CTRL1);
- wmb();
-
- r = __raw_readl(base + USB_DWC_CTRL3);
- r &= ~USB_DWC_CTRL3_OTG0_CKEN;
- __raw_writel(r, base + USB_DWC_CTRL3);
- wmb();
-
- __au1300_usb_phyctl(base, enable);
- }
-}
-
-static inline int au1300_usb_control(int block, int enable)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
- int ret = 0;
-
- switch (block) {
- case ALCHEMY_USB_OHCI0:
- __au1300_ohci_control(base, enable, 0);
- break;
- case ALCHEMY_USB_OHCI1:
- __au1300_ohci_control(base, enable, 1);
- break;
- case ALCHEMY_USB_EHCI0:
- __au1300_ehci_control(base, enable);
- break;
- case ALCHEMY_USB_UDC0:
- __au1300_udc_control(base, enable);
- break;
- case ALCHEMY_USB_OTG0:
- __au1300_otg_control(base, enable);
- break;
- default:
- ret = -ENODEV;
- }
- return ret;
-}
-
-static inline void au1300_usb_init(void)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
-
- /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4
- * here at all: Port 2 routing (EHCI or UDC) must be set either
- * by boot firmware or platform init code; I can't autodetect
- * a sane setting.
- */
- __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */
- wmb();
- __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */
- wmb();
- __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */
- wmb();
- __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */
- wmb();
- /* set coherent access bit */
- __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL);
- wmb();
-}
-
-static inline void __au1200_ohci_control(void __iomem *base, int enable)
-{
- unsigned long r = __raw_readl(base + AU1200_USBCFG);
- if (enable) {
- __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG);
- wmb();
- udelay(2000);
- } else {
- __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
- }
-}
-
-static inline void __au1200_ehci_control(void __iomem *base, int enable)
-{
- unsigned long r = __raw_readl(base + AU1200_USBCFG);
- if (enable) {
- __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
- } else {
- if (!(r & USBCFG_UCE)) /* UDC also off? */
- r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
- __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
- }
-}
-
-static inline void __au1200_udc_control(void __iomem *base, int enable)
-{
- unsigned long r = __raw_readl(base + AU1200_USBCFG);
- if (enable) {
- __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG);
- wmb();
- } else {
- if (!(r & USBCFG_ECE)) /* EHCI also off? */
- r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
- __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG);
- wmb();
- }
-}
-
-static inline int au1200_coherency_bug(void)
-{
-#if defined(CONFIG_DMA_COHERENT)
- /* Au1200 AB USB does not support coherent memory */
- if (!(read_c0_prid() & 0xff)) {
- printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n");
- printk(KERN_INFO "Au1200 USB: update your board or re-configure"
- " the kernel\n");
- return -ENODEV;
- }
-#endif
- return 0;
-}
-
-static inline int au1200_usb_control(int block, int enable)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
- int ret = 0;
-
- switch (block) {
- case ALCHEMY_USB_OHCI0:
- ret = au1200_coherency_bug();
- if (ret && enable)
- goto out;
- __au1200_ohci_control(base, enable);
- break;
- case ALCHEMY_USB_UDC0:
- __au1200_udc_control(base, enable);
- break;
- case ALCHEMY_USB_EHCI0:
- ret = au1200_coherency_bug();
- if (ret && enable)
- goto out;
- __au1200_ehci_control(base, enable);
- break;
- default:
- ret = -ENODEV;
- }
-out:
- return ret;
-}
-
-
-/* initialize USB block(s) to a known working state */
-static inline void au1200_usb_init(void)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
- __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG);
- wmb();
- udelay(1000);
-}
-
-static inline void au1000_usb_init(unsigned long rb, int reg)
-{
- void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
- unsigned long r = __raw_readl(base);
-
-#if defined(__BIG_ENDIAN)
- r |= USBHEN_BE;
-#endif
- r |= USBHEN_C;
-
- __raw_writel(r, base);
- wmb();
- udelay(1000);
-}
-
-
-static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
-{
- void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
- unsigned long r = __raw_readl(base + creg);
-
- if (enable) {
- __raw_writel(r | USBHEN_CE, base + creg);
- wmb();
- udelay(1000);
- __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg);
- wmb();
- udelay(1000);
-
- /* wait for reset complete (read reg twice: au1500 erratum) */
- while (__raw_readl(base + creg),
- !(__raw_readl(base + creg) & USBHEN_RD))
- udelay(1000);
- } else {
- __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
- wmb();
- }
-}
-
-static inline int au1000_usb_control(int block, int enable, unsigned long rb,
- int creg)
-{
- int ret = 0;
-
- switch (block) {
- case ALCHEMY_USB_OHCI0:
- __au1xx0_ohci_control(enable, rb, creg);
- break;
- default:
- ret = -ENODEV;
- }
- return ret;
-}
-
-/*
- * alchemy_usb_control - control Alchemy on-chip USB blocks
- * @block: USB block to target
- * @enable: set 1 to enable a block, 0 to disable
- */
-int alchemy_usb_control(int block, int enable)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&alchemy_usb_lock, flags);
- switch (alchemy_get_cputype()) {
- case ALCHEMY_CPU_AU1000:
- case ALCHEMY_CPU_AU1500:
- case ALCHEMY_CPU_AU1100:
- ret = au1000_usb_control(block, enable,
- AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1550:
- ret = au1000_usb_control(block, enable,
- AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1200:
- ret = au1200_usb_control(block, enable);
- break;
- case ALCHEMY_CPU_AU1300:
- ret = au1300_usb_control(block, enable);
- break;
- default:
- ret = -ENODEV;
- }
- spin_unlock_irqrestore(&alchemy_usb_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL_GPL(alchemy_usb_control);
-
-
-static unsigned long alchemy_usb_pmdata[2];
-
-static void au1000_usb_pm(unsigned long br, int creg, int susp)
-{
- void __iomem *base = (void __iomem *)KSEG1ADDR(br);
-
- if (susp) {
- alchemy_usb_pmdata[0] = __raw_readl(base + creg);
- /* There appears to be some undocumented reset register.... */
- __raw_writel(0, base + 0x04);
- wmb();
- __raw_writel(0, base + creg);
- wmb();
- } else {
- __raw_writel(alchemy_usb_pmdata[0], base + creg);
- wmb();
- }
-}
-
-static void au1200_usb_pm(int susp)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR);
- if (susp) {
- /* save OTG_CAP/MUX registers which indicate port routing */
- /* FIXME: write an OTG driver to do that */
- alchemy_usb_pmdata[0] = __raw_readl(base + 0x00);
- alchemy_usb_pmdata[1] = __raw_readl(base + 0x04);
- } else {
- /* restore access to all MMIO areas */
- au1200_usb_init();
-
- /* restore OTG_CAP/MUX registers */
- __raw_writel(alchemy_usb_pmdata[0], base + 0x00);
- __raw_writel(alchemy_usb_pmdata[1], base + 0x04);
- wmb();
- }
-}
-
-static void au1300_usb_pm(int susp)
-{
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
- /* remember Port2 routing */
- if (susp) {
- alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4);
- } else {
- au1300_usb_init();
- __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4);
- wmb();
- }
-}
-
-static void alchemy_usb_pm(int susp)
-{
- switch (alchemy_get_cputype()) {
- case ALCHEMY_CPU_AU1000:
- case ALCHEMY_CPU_AU1500:
- case ALCHEMY_CPU_AU1100:
- au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp);
- break;
- case ALCHEMY_CPU_AU1550:
- au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp);
- break;
- case ALCHEMY_CPU_AU1200:
- au1200_usb_pm(susp);
- break;
- case ALCHEMY_CPU_AU1300:
- au1300_usb_pm(susp);
- break;
- }
-}
-
-static int alchemy_usb_suspend(void)
-{
- alchemy_usb_pm(1);
- return 0;
-}
-
-static void alchemy_usb_resume(void)
-{
- alchemy_usb_pm(0);
-}
-
-static struct syscore_ops alchemy_usb_pm_ops = {
- .suspend = alchemy_usb_suspend,
- .resume = alchemy_usb_resume,
-};
-
-static int __init alchemy_usb_init(void)
-{
- switch (alchemy_get_cputype()) {
- case ALCHEMY_CPU_AU1000:
- case ALCHEMY_CPU_AU1500:
- case ALCHEMY_CPU_AU1100:
- au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1550:
- au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
- break;
- case ALCHEMY_CPU_AU1200:
- au1200_usb_init();
- break;
- case ALCHEMY_CPU_AU1300:
- au1300_usb_init();
- break;
- }
-
- register_syscore_ops(&alchemy_usb_pm_ops);
-
- return 0;
-}
-arch_initcall(alchemy_usb_init);
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
deleted file mode 100644
index 65c945eb4144..000000000000
--- a/drivers/usb/host/ehci-au1xxx.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * EHCI HCD (Host Controller Driver) for USB.
- *
- * Bus Glue for AMD Alchemy Au1xxx
- *
- * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
- *
- * Modified for AMD Alchemy Au1200 EHC
- * by K.Boge <karsten.boge@amd.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach-au1x00/au1000.h>
-
-
-extern int usb_disabled(void);
-
-static int au1xxx_ehci_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
-
- ehci->caps = hcd->regs;
- ret = ehci_setup(hcd);
-
- ehci->need_io_watchdog = 0;
- return ret;
-}
-
-static const struct hc_driver ehci_au1xxx_hc_driver = {
- .description = hcd_name,
- .product_desc = "Au1xxx EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- *
- * FIXME -- ehci_init() doesn't do enough here.
- * See ehci-ppc-soc for a complete implementation.
- */
- .reset = au1xxx_ehci_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ");
- return -ENOMEM;
- }
- hcd = usb_create_hcd(&ehci_au1xxx_hc_driver, &pdev->dev, "Au1xxx");
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (!hcd->regs) {
- pr_debug("devm_request_and_ioremap failed");
- ret = -ENOMEM;
- goto err1;
- }
-
- if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) {
- printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
- ret = -ENODEV;
- goto err1;
- }
-
- ret = usb_add_hcd(hcd, pdev->resource[1].start,
- IRQF_SHARED);
- if (ret == 0) {
- platform_set_drvdata(pdev, hcd);
- return ret;
- }
-
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- bool do_wakeup = device_may_wakeup(dev);
- int rc;
-
- rc = ehci_suspend(hcd, do_wakeup);
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
-
- return rc;
-}
-
-static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
-
- alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
- ehci_resume(hcd, false);
-
- return 0;
-}
-
-static const struct dev_pm_ops au1xxx_ehci_pmops = {
- .suspend = ehci_hcd_au1xxx_drv_suspend,
- .resume = ehci_hcd_au1xxx_drv_resume,
-};
-
-#define AU1XXX_EHCI_PMOPS &au1xxx_ehci_pmops
-
-#else
-#define AU1XXX_EHCI_PMOPS NULL
-#endif
-
-static struct platform_driver ehci_hcd_au1xxx_driver = {
- .probe = ehci_hcd_au1xxx_drv_probe,
- .remove = ehci_hcd_au1xxx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "au1xxx-ehci",
- .owner = THIS_MODULE,
- .pm = AU1XXX_EHCI_PMOPS,
- }
-};
-
-MODULE_ALIAS("platform:au1xxx-ehci");
diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c
deleted file mode 100644
index d91708d2e729..000000000000
--- a/drivers/usb/host/ehci-cns3xxx.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2008 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/atomic.h>
-#include <mach/cns3xxx.h>
-#include <mach/pm.h>
-
-static int cns3xxx_ehci_init(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- *
- * Set USB AHB INCR length to 16
- */
- if (atomic_inc_return(&usb_pwr_ref) == 1) {
- cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
- cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
- cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
- __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
- MISC_CHIP_CONFIG_REG);
- }
-
- ehci->caps = hcd->regs;
-
- hcd->has_tt = 0;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
-static const struct hc_driver cns3xxx_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "CNS3XXX EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
- .reset = cns3xxx_ehci_init,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
- .get_frame_number = ehci_get_frame,
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
-#endif
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int cns3xxx_ehci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &cns3xxx_ehci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "Found HC with no IRQ.\n");
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "Found HC with no register addr.\n");
- retval = -ENODEV;
- goto err1;
- }
-
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err1;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval == 0)
- return retval;
-
-err1:
- usb_put_hcd(hcd);
-
- return retval;
-}
-
-static int cns3xxx_ehci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- */
- if (atomic_dec_return(&usb_pwr_ref) == 0)
- cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
-
- usb_put_hcd(hcd);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:cns3xxx-ehci");
-
-static struct platform_driver cns3xxx_ehci_driver = {
- .probe = cns3xxx_ehci_probe,
- .remove = cns3xxx_ehci_remove,
- .driver = {
- .name = "cns3xxx-ehci",
- },
-};
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 1599806e3d47..dfd3bf3aa4de 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -18,21 +18,6 @@
/* this file is part of ehci-hcd.c */
-#define ehci_dbg(ehci, fmt, args...) \
- dev_dbg (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_err(ehci, fmt, args...) \
- dev_err (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_info(ehci, fmt, args...) \
- dev_info (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-#define ehci_warn(ehci, fmt, args...) \
- dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-
-#ifdef VERBOSE_DEBUG
-# define ehci_vdbg ehci_dbg
-#else
- static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {}
-#endif
-
#ifdef DEBUG
/* check the values in the HCSPARAMS register
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6bf6c42481e8..9c2afb516fe5 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -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
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 914ce9370e70..a7ec827ca2ca 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -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
index f224c0a48bed..000000000000
--- a/drivers/usb/host/ehci-ixp4xx.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * IXP4XX EHCI Host Controller Driver
- *
- * Author: Vladimir Barinov <vbarinov@embeddedalley.com>
- *
- * Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/platform_device.h>
-
-static int ixp4xx_ehci_init(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval = 0;
-
- ehci->big_endian_desc = 1;
- ehci->big_endian_mmio = 1;
-
- ehci->caps = hcd->regs + 0x100;
-
- hcd->has_tt = 1;
-
- retval = ehci_setup(hcd);
- if (retval)
- return retval;
-
- ehci_port_power(ehci, 0);
-
- return retval;
-}
-
-static const struct hc_driver ixp4xx_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "IXP4XX EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
- .reset = ixp4xx_ehci_init,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
- .get_frame_number = ehci_get_frame,
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
-#if defined(CONFIG_PM)
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
-#endif
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ixp4xx_ehci_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &ixp4xx_ehci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd) {
- retval = -ENOMEM;
- goto fail_create_hcd;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no register addr. Check %s setup!\n",
- dev_name(&pdev->dev));
- retval = -ENODEV;
- goto fail_request_resource;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto fail_request_resource;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval)
- goto fail_request_resource;
-
- return retval;
-
-fail_request_resource:
- usb_put_hcd(hcd);
-fail_create_hcd:
- dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
- return retval;
-}
-
-static int ixp4xx_ehci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:ixp4xx-ehci");
-
-static struct platform_driver ixp4xx_ehci_driver = {
- .probe = ixp4xx_ehci_probe,
- .remove = ixp4xx_ehci_remove,
- .driver = {
- .name = "ixp4xx-ehci",
- },
-};
diff --git a/drivers/usb/host/ehci-lpm.c b/drivers/usb/host/ehci-lpm.c
index 2111627a19de..6b092c1dff64 100644
--- a/drivers/usb/host/ehci-lpm.c
+++ b/drivers/usb/host/ehci-lpm.c
@@ -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
index ca759652626b..000000000000
--- a/drivers/usb/host/ehci-ls1x.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Bus Glue for Loongson LS1X built-in EHCI controller.
- *
- * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-
-#include <linux/platform_device.h>
-
-static int ehci_ls1x_reset(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
-
- ehci->caps = hcd->regs;
-
- ret = ehci_setup(hcd);
- if (ret)
- return ret;
-
- ehci_port_power(ehci, 0);
-
- return 0;
-}
-
-static const struct hc_driver ehci_ls1x_hc_driver = {
- .description = hcd_name,
- .product_desc = "LOONGSON1 EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_ls1x_reset,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int irq;
- int ret;
-
- pr_debug("initializing loongson1 ehci USB Controller\n");
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- irq = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev,
- "Found HC with no register addr. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev,
- dev_name(&pdev->dev));
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- ret = -EFAULT;
- goto err_put_hcd;
- }
-
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret)
- goto err_put_hcd;
-
- return ret;
-
-err_put_hcd:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ehci_hcd_ls1x_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ehci_ls1x_driver = {
- .probe = ehci_hcd_ls1x_probe,
- .remove = ehci_hcd_ls1x_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ls1x-ehci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci");
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 2cb7d370c4ef..7880ba621f89 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -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",
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 764e0100b6f4..272728c48c9e 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -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);
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 85b74be202eb..abc178d21fe4 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -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);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 7cf3da7babf0..2e14714b359f 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -36,29 +36,6 @@
static int ehci_get_frame (struct usb_hcd *hcd);
-#ifdef CONFIG_PCI
-
-static unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
-{
- unsigned uf;
-
- /*
- * The MosChip MCS9990 controller updates its microframe counter
- * a little before the frame counter, and occasionally we will read
- * the invalid intermediate value. Avoid problems by checking the
- * microframe number (the low-order 3 bits); if they are 0 then
- * re-read the register to get the correct value.
- */
- uf = ehci_readl(ehci, &ehci->regs->frame_index);
- if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0)))
- uf = ehci_readl(ehci, &ehci->regs->frame_index);
- return uf;
-}
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
/*
* periodic_next_shadow - return "next" pointer on shadow list
* @periodic: host pointer to qh/itd/sitd
@@ -1361,7 +1338,7 @@ sitd_slot_ok (
* given EHCI_TUNE_FLS and the slop). Or, write a smarter scheduler!
*/
-#define SCHEDULE_SLOP 80 /* microframes */
+#define SCHEDULING_DELAY 40 /* microframes */
static int
iso_stream_schedule (
@@ -1370,7 +1347,7 @@ iso_stream_schedule (
struct ehci_iso_stream *stream
)
{
- u32 now, next, start, period, span;
+ u32 now, base, next, start, period, span;
int status;
unsigned mod = ehci->periodic_size << 3;
struct ehci_iso_sched *sched = urb->hcpriv;
@@ -1382,62 +1359,72 @@ iso_stream_schedule (
span <<= 3;
}
- if (span > mod - SCHEDULE_SLOP) {
- ehci_dbg (ehci, "iso request %p too long\n", urb);
- status = -EFBIG;
- goto fail;
- }
-
now = ehci_read_frame_index(ehci) & (mod - 1);
/* Typical case: reuse current schedule, stream is still active.
* Hopefully there are no gaps from the host falling behind
- * (irq delays etc), but if there are we'll take the next
- * slot in the schedule, implicitly assuming URB_ISO_ASAP.
+ * (irq delays etc). If there are, the behavior depends on
+ * whether URB_ISO_ASAP is set.
*/
if (likely (!list_empty (&stream->td_list))) {
- u32 excess;
- /* For high speed devices, allow scheduling within the
- * isochronous scheduling threshold. For full speed devices
- * and Intel PCI-based controllers, don't (work around for
- * Intel ICH9 bug).
- */
- if (!stream->highspeed && ehci->fs_i_thresh)
- next = now + ehci->i_thresh;
+ /* Take the isochronous scheduling threshold into account */
+ if (ehci->i_thresh)
+ next = now + ehci->i_thresh; /* uframe cache */
else
- next = now;
+ next = (now + 2 + 7) & ~0x07; /* full frame cache */
- /* Fell behind (by up to twice the slop amount)?
- * We decide based on the time of the last currently-scheduled
- * slot, not the time of the next available slot.
+ /*
+ * Use ehci->last_iso_frame as the base. There can't be any
+ * TDs scheduled for earlier than that.
*/
- excess = (stream->next_uframe - period - next) & (mod - 1);
- if (excess >= mod - 2 * SCHEDULE_SLOP)
- start = next + excess - mod + period *
- DIV_ROUND_UP(mod - excess, period);
- else
- start = next + excess + period;
- if (start - now >= mod) {
- ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
- urb, start - now - period, period,
- mod);
- status = -EFBIG;
+ base = ehci->last_iso_frame << 3;
+ next = (next - base) & (mod - 1);
+ start = (stream->next_uframe - base) & (mod - 1);
+
+ /* Is the schedule already full? */
+ if (unlikely(start < period)) {
+ ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n",
+ urb, stream->next_uframe, base,
+ period, mod);
+ status = -ENOSPC;
goto fail;
}
+
+ /* Behind the scheduling threshold? */
+ if (unlikely(start < next)) {
+
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ start += (next - start + period - 1) & -period;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
+ */
+ else if (start + span - period < next) {
+ ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n",
+ urb, start + base,
+ span - period, next + base);
+ status = -EXDEV;
+ goto fail;
+ }
+ }
+
+ start += base;
}
/* need to schedule; when's the next (u)frame we could start?
* this is bigger than ehci->i_thresh allows; scheduling itself
- * isn't free, the slop should handle reasonably slow cpus. it
+ * isn't free, the delay should handle reasonably slow cpus. it
* can also help high bandwidth if the dma and irq loads don't
* jump until after the queue is primed.
*/
else {
int done = 0;
- start = SCHEDULE_SLOP + (now & ~0x07);
- /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
+ base = now & ~0x07;
+ start = base + SCHEDULING_DELAY;
/* find a uframe slot with enough bandwidth.
* Early uframes are more precious because full-speed
@@ -1464,19 +1451,16 @@ iso_stream_schedule (
/* no room in the schedule */
if (!done) {
- ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
- urb, now, now + mod);
+ ehci_dbg(ehci, "iso sched full %p", urb);
status = -ENOSPC;
goto fail;
}
}
/* Tried to schedule too far into the future? */
- if (unlikely(start - now + span - period
- >= mod - 2 * SCHEDULE_SLOP)) {
- ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
- urb, start - now, span - period,
- mod - 2 * SCHEDULE_SLOP);
+ if (unlikely(start - base + span - period >= mod)) {
+ ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n",
+ urb, start - base, span - period, mod);
status = -EFBIG;
goto fail;
}
@@ -1490,7 +1474,7 @@ iso_stream_schedule (
/* Make sure scan_isoc() sees these */
if (ehci->isoc_count == 0)
- ehci->next_frame = now >> 3;
+ ehci->last_iso_frame = now >> 3;
return 0;
fail:
@@ -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;
}
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 6223d1757848..2de089001ae9 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -28,7 +28,10 @@
#include <linux/pm_runtime.h>
#include <linux/usb/tegra_usb_phy.h>
-#include <mach/iomap.h>
+
+#define TEGRA_USB_BASE 0xC5000000
+#define TEGRA_USB2_BASE 0xC5004000
+#define TEGRA_USB3_BASE 0xC5008000
#define TEGRA_USB_DMA_ALIGN 32
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
index d3c9a3e397b9..c6fe0bb619cb 100644
--- a/drivers/usb/host/ehci-vt8500.c
+++ b/drivers/usb/host/ehci-vt8500.c
@@ -19,22 +19,6 @@
#include <linux/of.h>
#include <linux/platform_device.h>
-static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int rc = 0;
-
- if (!udev->parent) /* udev is root hub itself, impossible */
- rc = -1;
- /* we only support lpm device connected to root hub yet */
- if (ehci->has_lpm && !udev->parent->parent) {
- rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
- if (!rc)
- rc = ehci_lpm_check(ehci, udev->portnum);
- }
- return rc;
-}
-
static const struct hc_driver vt8500_ehci_hc_driver = {
.description = hcd_name,
.product_desc = "VT8500 EHCI",
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c
index ec598082c14b..fdd7c4873cf2 100644
--- a/drivers/usb/host/ehci-w90x900.c
+++ b/drivers/usb/host/ehci-w90x900.c
@@ -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
index 8dc6a22d90b8..000000000000
--- a/drivers/usb/host/ehci-xls.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * EHCI HCD for Netlogic XLS processors.
- *
- * (C) Copyright 2011 Netlogic Microsystems Inc.
- *
- * Based on various ehci-*.c drivers
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/platform_device.h>
-
-static int ehci_xls_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-
- ehci->caps = hcd->regs;
-
- return ehci_setup(hcd);
-}
-
-int ehci_xls_probe_internal(const struct hc_driver *driver,
- struct platform_device *pdev)
-{
- struct usb_hcd *hcd;
- struct resource *res;
- int retval, irq;
-
- /* Get our IRQ from an earlier registered Platform Resource */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
-
- /* Get our Memory Handle */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Error: MMIO Handle %s setup!\n",
- dev_name(&pdev->dev));
- return -ENODEV;
- }
- hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
- if (!hcd) {
- retval = -ENOMEM;
- goto err1;
- }
-
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(&pdev->dev, "controller already in use\n");
- retval = -EBUSY;
- goto err2;
- }
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
-
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err3;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval != 0)
- goto err4;
- return retval;
-
-err4:
- iounmap(hcd->regs);
-err3:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err2:
- usb_put_hcd(hcd);
-err1:
- dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev),
- retval);
- return retval;
-}
-
-static struct hc_driver ehci_xls_hc_driver = {
- .description = hcd_name,
- .product_desc = "XLS EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .irq = ehci_irq,
- .flags = HCD_USB2 | HCD_MEMORY,
- .reset = ehci_xls_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
-
- .get_frame_number = ehci_get_frame,
-
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
-static int ehci_xls_probe(struct platform_device *pdev)
-{
- if (usb_disabled())
- return -ENODEV;
-
- return ehci_xls_probe_internal(&ehci_xls_hc_driver, pdev);
-}
-
-static int ehci_xls_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- return 0;
-}
-
-MODULE_ALIAS("ehci-xls");
-
-static struct platform_driver ehci_xls_driver = {
- .probe = ehci_xls_probe,
- .remove = ehci_xls_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ehci-xls",
- },
-};
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index da07d98f7d1d..ec948c3b1cea 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -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 */
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index fff114fd5461..958379f9de79 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -43,7 +43,6 @@ static int of_isp1760_probe(struct platform_device *dev)
struct device_node *dp = dev->dev.of_node;
struct resource *res;
struct resource memory;
- struct of_irq oirq;
int virq;
resource_size_t res_len;
int ret;
@@ -69,14 +68,12 @@ static int of_isp1760_probe(struct platform_device *dev)
goto free_data;
}
- if (of_irq_map_one(dp, 0, &oirq)) {
+ virq = irq_of_parse_and_map(dp, 0);
+ if (!virq) {
ret = -ENODEV;
goto release_reg;
}
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
-
if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
devflags |= ISP1760_FLAG_ISP1761;
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 0bf72f943b00..908d84af1dd7 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -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
index c611699b4aa6..000000000000
--- a/drivers/usb/host/ohci-au1xxx.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Copyright 2002 Hewlett-Packard Company
- *
- * Bus Glue for AMD Alchemy Au1xxx
- *
- * Written by Christopher Hoover <ch@hpl.hp.com>
- * Based on fragments of previous driver by Russell King et al.
- *
- * Modified for LH7A404 from ohci-sa1111.c
- * by Durgesh Pattamatta <pattamattad@sharpsec.com>
- * Modified for AMD Alchemy Au1xxx
- * by Matt Porter <mporter@kernel.crashing.org>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-#include <asm/mach-au1x00/au1000.h>
-
-
-extern int usb_disabled(void);
-
-static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- ohci_dbg(ohci, "ohci_au1xxx_start, ohci:%p", ohci);
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run(ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
-
- return 0;
-}
-
-static const struct hc_driver ohci_au1xxx_hc_driver = {
- .description = hcd_name,
- .product_desc = "Au1xxx OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_au1xxx_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
-{
- int ret, unit;
- struct usb_hcd *hcd;
-
- if (usb_disabled())
- return -ENODEV;
-
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ\n");
- return -ENOMEM;
- }
-
- hcd = usb_create_hcd(&ohci_au1xxx_hc_driver, &pdev->dev, "au1xxx");
- if (!hcd)
- return -ENOMEM;
-
- hcd->rsrc_start = pdev->resource[0].start;
- hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_debug("request_mem_region failed\n");
- ret = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- pr_debug("ioremap failed\n");
- ret = -ENOMEM;
- goto err2;
- }
-
- unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
- ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
- if (alchemy_usb_control(unit, 1)) {
- printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
- ret = -ENODEV;
- goto err3;
- }
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- ret = usb_add_hcd(hcd, pdev->resource[1].start,
- IRQF_SHARED);
- if (ret == 0) {
- platform_set_drvdata(pdev, hcd);
- return ret;
- }
-
- alchemy_usb_control(unit, 0);
-err3:
- iounmap(hcd->regs);
-err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
- usb_put_hcd(hcd);
- return ret;
-}
-
-static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
- int unit;
-
- unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
- ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
- usb_remove_hcd(hcd);
- alchemy_usb_control(unit, 0);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- unsigned long flags;
- int rc;
-
- rc = 0;
-
- /* Root hub was already suspended. Disable irq emission and
- * mark HW unaccessible, bail out if RH has been resumed. Use
- * the spinlock to properly synchronize with possible pending
- * RH suspend or resume activity.
- */
- spin_lock_irqsave(&ohci->lock, flags);
- if (ohci->rh_state != OHCI_RH_SUSPENDED) {
- rc = -EINVAL;
- goto bail;
- }
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
- (void)ohci_readl(ohci, &ohci->regs->intrdisable);
-
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
-bail:
- spin_unlock_irqrestore(&ohci->lock, flags);
-
- return rc;
-}
-
-static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
-{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
-
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 1);
-
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- ohci_finish_controller_resume(hcd);
-
- return 0;
-}
-
-static const struct dev_pm_ops au1xxx_ohci_pmops = {
- .suspend = ohci_hcd_au1xxx_drv_suspend,
- .resume = ohci_hcd_au1xxx_drv_resume,
-};
-
-#define AU1XXX_OHCI_PMOPS &au1xxx_ohci_pmops
-
-#else
-#define AU1XXX_OHCI_PMOPS NULL
-#endif
-
-static struct platform_driver ohci_hcd_au1xxx_driver = {
- .probe = ohci_hcd_au1xxx_drv_probe,
- .remove = ohci_hcd_au1xxx_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "au1xxx-ohci",
- .owner = THIS_MODULE,
- .pm = AU1XXX_OHCI_PMOPS,
- },
-};
-
-MODULE_ALIAS("platform:au1xxx-ohci");
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c
deleted file mode 100644
index 2c9f233047be..000000000000
--- a/drivers/usb/host/ohci-cns3xxx.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2008 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/atomic.h>
-#include <mach/cns3xxx.h>
-#include <mach/pm.h>
-
-static int __devinit
-cns3xxx_ohci_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- *
- * Set USB AHB INCR length to 16
- */
- if (atomic_inc_return(&usb_pwr_ref) == 1) {
- cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
- cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
- cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
- __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
- MISC_CHIP_CONFIG_REG);
- }
-
- ret = ohci_init(ohci);
- if (ret < 0)
- return ret;
-
- ohci->num_ports = 1;
-
- ret = ohci_run(ohci);
- if (ret < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
- return 0;
-}
-
-static const struct hc_driver cns3xxx_ohci_hc_driver = {
- .description = hcd_name,
- .product_desc = "CNS3XXX OHCI Host controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
- .start = cns3xxx_ohci_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
- .get_frame_number = ohci_get_frame,
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int cns3xxx_ohci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
- const struct hc_driver *driver = &cns3xxx_ohci_hc_driver;
- struct resource *res;
- int irq;
- int retval;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "Found HC with no IRQ.\n");
- return -ENODEV;
- }
- irq = res->start;
-
- hcd = usb_create_hcd(driver, dev, dev_name(dev));
- if (!hcd)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "Found HC with no register addr.\n");
- retval = -ENODEV;
- goto err1;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(dev, "controller already in use\n");
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_dbg(dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err2;
- }
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval == 0)
- return retval;
-
- iounmap(hcd->regs);
-err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-static int cns3xxx_ohci_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-
- /*
- * EHCI and OHCI share the same clock and power,
- * resetting twice would cause the 1st controller been reset.
- * Therefore only do power up at the first up device, and
- * power down at the last down device.
- */
- if (atomic_dec_return(&usb_pwr_ref) == 0)
- cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
-
- usb_put_hcd(hcd);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-MODULE_ALIAS("platform:cns3xxx-ohci");
-
-static struct platform_driver ohci_hcd_cns3xxx_driver = {
- .probe = cns3xxx_ohci_probe,
- .remove = cns3xxx_ohci_remove,
- .driver = {
- .name = "cns3xxx-ohci",
- },
-};
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index dbfbd1dfd2e2..a982f04ed787 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -194,7 +194,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
ep93xx_start_hc(&pdev->dev);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#endif
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 20a50081f922..2f303295b428 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -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;
}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 4a1d64d92338..180a2b01db56 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -231,13 +231,41 @@ static int ohci_urb_enqueue (
frame &= ~(ed->interval - 1);
frame |= ed->branch;
urb->start_frame = frame;
+ }
+ } else if (ed->type == PIPE_ISOCHRONOUS) {
+ u16 next = ohci_frame_no(ohci) + 2;
+ u16 frame = ed->last_iso + ed->interval;
+
+ /* Behind the scheduling threshold? */
+ if (unlikely(tick_before(frame, next))) {
- /* yes, only URB_ISO_ASAP is supported, and
- * urb->start_frame is never used as input.
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ frame += (next - frame + ed->interval - 1) &
+ -ed->interval;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
*/
+ else if (tick_before(frame + ed->interval *
+ (urb->number_of_packets - 1), next)) {
+ retval = -EXDEV;
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ goto fail;
+ }
+
+ /*
+ * Some OHCI hardware doesn't handle late TDs
+ * correctly. After retiring them it proceeds to
+ * the next ED instead of the next TD. Therefore
+ * we have to omit the late TDs entirely.
+ */
+ urb_priv->td_cnt = DIV_ROUND_UP(next - frame,
+ ed->interval);
}
- } else if (ed->type == PIPE_ISOCHRONOUS)
- urb->start_frame = ed->last_iso + ed->interval;
+ urb->start_frame = frame;
+ }
/* fill the TDs and link them to the ed; and
* enable that part of the schedule, if needed
@@ -983,6 +1011,79 @@ static int ohci_restart (struct ohci_hcd *ohci)
#endif
+#ifdef CONFIG_PM
+
+static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ unsigned long flags;
+
+ /* Disable irq emission and mark HW unaccessible. Use
+ * the spinlock to properly synchronize with possible pending
+ * RH suspend or resume activity.
+ */
+ spin_lock_irqsave (&ohci->lock, flags);
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ (void)ohci_readl(ohci, &ohci->regs->intrdisable);
+
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ spin_unlock_irqrestore (&ohci->lock, flags);
+
+ return 0;
+}
+
+
+static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int port;
+ bool need_reinit = false;
+
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+ /* Make sure resume from hibernation re-enumerates everything */
+ if (hibernated)
+ ohci_usb_reset(ohci);
+
+ /* See if the controller is already running or has been reset */
+ ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+ if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
+ need_reinit = true;
+ } else {
+ switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+ case OHCI_USB_OPER:
+ case OHCI_USB_RESET:
+ need_reinit = true;
+ }
+ }
+
+ /* If needed, reinitialize and suspend the root hub */
+ if (need_reinit) {
+ spin_lock_irq(&ohci->lock);
+ ohci_rh_resume(ohci);
+ ohci_rh_suspend(ohci, 0);
+ spin_unlock_irq(&ohci->lock);
+ }
+
+ /* Normally just turn on port power and enable interrupts */
+ else {
+ ohci_dbg(ohci, "powerup ports\n");
+ for (port = 0; port < ohci->num_ports; port++)
+ ohci_writel(ohci, RH_PS_PPS,
+ &ohci->regs->roothub.portstatus[port]);
+
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
+ ohci_readl(ohci, &ohci->regs->intrenable);
+ msleep(20);
+ }
+
+ usb_hcd_resume_root_hub(hcd);
+
+ return 0;
+}
+
+#endif
+
/*-------------------------------------------------------------------------*/
MODULE_AUTHOR (DRIVER_AUTHOR);
@@ -1029,21 +1130,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_ep93xx_driver
#endif
-#ifdef CONFIG_MIPS_ALCHEMY
-#include "ohci-au1xxx.c"
-#define PLATFORM_DRIVER ohci_hcd_au1xxx_driver
-#endif
-
-#ifdef CONFIG_PNX8550
-#include "ohci-pnx8550.c"
-#define PLATFORM_DRIVER ohci_hcd_pnx8550_driver
-#endif
-
-#ifdef CONFIG_USB_OHCI_HCD_PPC_SOC
-#include "ohci-ppc-soc.c"
-#define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver
-#endif
-
#ifdef CONFIG_ARCH_AT91
#include "ohci-at91.c"
#define PLATFORM_DRIVER ohci_hcd_at91_driver
@@ -1059,11 +1145,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_da8xx_driver
#endif
-#ifdef CONFIG_USB_OHCI_SH
-#include "ohci-sh.c"
-#define PLATFORM_DRIVER ohci_hcd_sh_driver
-#endif
-
#ifdef CONFIG_USB_OHCI_HCD_PPC_OF
#include "ohci-ppc-of.c"
@@ -1105,16 +1186,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_tilegx_driver
#endif
-#ifdef CONFIG_USB_CNS3XXX_OHCI
-#include "ohci-cns3xxx.c"
-#define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
-#endif
-
-#ifdef CONFIG_CPU_XLR
-#include "ohci-xls.c"
-#define PLATFORM_DRIVER ohci_xls_driver
-#endif
-
#ifdef CONFIG_USB_OHCI_HCD_PLATFORM
#include "ohci-platform.c"
#define PLATFORM_DRIVER ohci_platform_driver
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 2f3619eefefa..db09dae7b557 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -316,48 +316,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
return rc;
}
-/* Carry out the final steps of resuming the controller device */
-static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int port;
- bool need_reinit = false;
-
- /* See if the controller is already running or has been reset */
- ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
- if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
- need_reinit = true;
- } else {
- switch (ohci->hc_control & OHCI_CTRL_HCFS) {
- case OHCI_USB_OPER:
- case OHCI_USB_RESET:
- need_reinit = true;
- }
- }
-
- /* If needed, reinitialize and suspend the root hub */
- if (need_reinit) {
- spin_lock_irq(&ohci->lock);
- ohci_rh_resume(ohci);
- ohci_rh_suspend(ohci, 0);
- spin_unlock_irq(&ohci->lock);
- }
-
- /* Normally just turn on port power and enable interrupts */
- else {
- ohci_dbg(ohci, "powerup ports\n");
- for (port = 0; port < ohci->num_ports; port++)
- ohci_writel(ohci, RH_PS_PPS,
- &ohci->regs->roothub.portstatus[port]);
-
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
- ohci_readl(ohci, &ohci->regs->intrenable);
- msleep(20);
- }
-
- usb_hcd_resume_root_hub(hcd);
-}
-
/* Carry out polling-, autostop-, and autoresume-related state changes */
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
int any_connected, int rhsc_status)
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 4531d03503c3..733c77c36355 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -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;
}
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 1843bb68ac7c..6afa7dc4e4c3 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -296,49 +296,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
return ret;
}
-#ifdef CONFIG_PM
-
-static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- unsigned long flags;
- int rc = 0;
-
- /* Root hub was already suspended. Disable irq emission and
- * mark HW unaccessible, bail out if RH has been resumed. Use
- * the spinlock to properly synchronize with possible pending
- * RH suspend or resume activity.
- */
- spin_lock_irqsave (&ohci->lock, flags);
- if (ohci->rh_state != OHCI_RH_SUSPENDED) {
- rc = -EINVAL;
- goto bail;
- }
- ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
- (void)ohci_readl(ohci, &ohci->regs->intrdisable);
-
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- bail:
- spin_unlock_irqrestore (&ohci->lock, flags);
-
- return rc;
-}
-
-
-static int ohci_pci_resume(struct usb_hcd *hcd, bool hibernated)
-{
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- /* Make sure resume from hibernation re-enumerates everything */
- if (hibernated)
- ohci_usb_reset(hcd_to_ohci(hcd));
-
- ohci_finish_controller_resume(hcd);
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
/*-------------------------------------------------------------------------*/
@@ -362,8 +319,8 @@ static const struct hc_driver ohci_pci_hc_driver = {
.shutdown = ohci_shutdown,
#ifdef CONFIG_PM
- .pci_suspend = ohci_pci_suspend,
- .pci_resume = ohci_pci_resume,
+ .pci_suspend = ohci_suspend,
+ .pci_resume = ohci_resume,
#endif
/*
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index e24ec9f79164..bda4e0bb8ab3 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -31,6 +31,10 @@ static int ohci_platform_reset(struct usb_hcd *hcd)
ohci->flags |= OHCI_QUIRK_FRAME_NO;
ohci_hcd_init(ohci);
+
+ if (pdata->num_ports)
+ ohci->num_ports = pdata->num_ports;
+
err = ohci_init(ohci);
return err;
@@ -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
index 148d27d6a67c..000000000000
--- a/drivers/usb/host/ohci-pnx8550.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Copyright 2002 Hewlett-Packard Company
- * (C) Copyright 2005 Embedded Alley Solutions, Inc.
- *
- * Bus Glue for PNX8550
- *
- * Written by Christopher Hoover <ch@hpl.hp.com>
- * Based on fragments of previous driver by Russell King et al.
- *
- * Modified for LH7A404 from ohci-sa1111.c
- * by Durgesh Pattamatta <pattamattad@sharpsec.com>
- *
- * Modified for PNX8550 from ohci-sa1111.c and sa-omap.c
- * by Vitaly Wool <vitalywool@gmail.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <asm/mach-pnx8550/usb.h>
-#include <asm/mach-pnx8550/int.h>
-#include <asm/mach-pnx8550/pci.h>
-
-#ifndef CONFIG_PNX8550
-#error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined."
-#endif
-
-extern int usb_disabled(void);
-
-/*-------------------------------------------------------------------------*/
-
-static void pnx8550_start_hc(struct platform_device *dev)
-{
- /*
- * Set register CLK48CTL to enable and 48MHz
- */
- outl(0x00000003, PCI_BASE | 0x0004770c);
-
- /*
- * Set register CLK12CTL to enable and 48MHz
- */
- outl(0x00000003, PCI_BASE | 0x00047710);
-
- udelay(100);
-}
-
-static void pnx8550_stop_hc(struct platform_device *dev)
-{
- udelay(10);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
-
-/**
- * usb_hcd_pnx8550_probe - initialize pnx8550-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- */
-int usb_hcd_pnx8550_probe (const struct hc_driver *driver,
- struct platform_device *dev)
-{
- int retval;
- struct usb_hcd *hcd;
-
- if (dev->resource[0].flags != IORESOURCE_MEM ||
- dev->resource[1].flags != IORESOURCE_IRQ) {
- dev_err (&dev->dev,"invalid resource type\n");
- return -ENOMEM;
- }
-
- hcd = usb_create_hcd (driver, &dev->dev, "pnx8550");
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = dev->resource[0].start;
- hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] "
- "failed\n", hcd->rsrc_start, hcd->rsrc_len);
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n",
- hcd->rsrc_start, hcd->rsrc_len);
- retval = -ENOMEM;
- goto err2;
- }
-
- pnx8550_start_hc(dev);
-
- ohci_hcd_init(hcd_to_ohci(hcd));
-
- retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
- if (retval == 0)
- return retval;
-
- pnx8550_stop_hc(dev);
- iounmap(hcd->regs);
- err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs
- * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking
- * the HCD's stop() method. It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev)
-{
- usb_remove_hcd(hcd);
- pnx8550_stop_hc(dev);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int __devinit
-ohci_pnx8550_start (struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
- ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci);
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run (ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s",
- hcd->self.bus_name);
- ohci_stop (hcd);
- return ret;
- }
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_pnx8550_hc_driver = {
- .description = hcd_name,
- .product_desc = "PNX8550 OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_pnx8550_start,
- .stop = ohci_stop,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_pnx8550_drv_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev);
- return ret;
-}
-
-static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_hcd_pnx8550_remove(hcd, pdev);
- return 0;
-}
-
-MODULE_ALIAS("platform:pnx8550-ohci");
-
-static struct platform_driver ohci_hcd_pnx8550_driver = {
- .driver = {
- .name = "pnx8550-ohci",
- .owner = THIS_MODULE,
- },
- .probe = ohci_hcd_pnx8550_drv_probe,
- .remove = ohci_hcd_pnx8550_drv_remove,
-};
-
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
deleted file mode 100644
index 185c39ed81b7..000000000000
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Copyright 2002 Hewlett-Packard Company
- * (C) Copyright 2003-2005 MontaVista Software Inc.
- *
- * Bus Glue for PPC On-Chip OHCI driver
- * Tested on Freescale MPC5200 and IBM STB04xxx
- *
- * Modified by Dale Farnsworth <dale@farnsworth.org> from ohci-sa1111.c
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
-/**
- * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller.
- *
- * Store this function in the HCD's struct pci_driver as probe().
- */
-static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
- struct platform_device *pdev)
-{
- int retval;
- struct usb_hcd *hcd;
- struct ohci_hcd *ohci;
- struct resource *res;
- int irq;
-
- pr_debug("initializing PPC-SOC USB Controller\n");
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- pr_debug("%s: no irq\n", __FILE__);
- return -ENODEV;
- }
- irq = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- pr_debug("%s: no reg addr\n", __FILE__);
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(driver, &pdev->dev, "PPC-SOC USB");
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_debug("%s: request_mem_region failed\n", __FILE__);
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- pr_debug("%s: ioremap failed\n", __FILE__);
- retval = -ENOMEM;
- goto err2;
- }
-
- ohci = hcd_to_ohci(hcd);
- ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
-
-#ifdef CONFIG_PPC_MPC52xx
- /* MPC52xx doesn't need frame_no shift */
- ohci->flags |= OHCI_QUIRK_FRAME_NO;
-#endif
- ohci_hcd_init(ohci);
-
- retval = usb_add_hcd(hcd, irq, 0);
- if (retval == 0)
- return retval;
-
- pr_debug("Removing PPC-SOC USB Controller\n");
-
- iounmap(hcd->regs);
- err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_hcd_ppc_soc_remove - shutdown processing for On-Chip HCDs
- * @pdev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_ppc_soc_probe().
- * It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd,
- struct platform_device *pdev)
-{
- usb_remove_hcd(hcd);
-
- pr_debug("stopping PPC-SOC USB Controller\n");
-
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-}
-
-static int __devinit
-ohci_ppc_soc_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run(ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
-
- return 0;
-}
-
-static const struct hc_driver ohci_ppc_soc_hc_driver = {
- .description = hcd_name,
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_ppc_soc_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int ohci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- ret = usb_hcd_ppc_soc_probe(&ohci_ppc_soc_hc_driver, pdev);
- return ret;
-}
-
-static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_hcd_ppc_soc_remove(hcd, pdev);
- return 0;
-}
-
-static struct platform_driver ohci_hcd_ppc_soc_driver = {
- .probe = ohci_hcd_ppc_soc_drv_probe,
- .remove = ohci_hcd_ppc_soc_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
-#ifdef CONFIG_PM
- /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
- /*.resume = ohci_hcd_ppc_soc_drv_resume,*/
-#endif
- .driver = {
- .name = "ppc-soc-ohci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS("platform:ppc-soc-ohci");
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 2bf11440b010..156d289d3bb5 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -591,7 +591,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
/* Select Power Management Mode */
pxa27x_ohci_select_pmm(ohci, inf->port_mode);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index c5a1ea9145fa..177a213790d4 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -596,7 +596,6 @@ static void td_submit_urb (
urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C);
}
- urb_priv->td_cnt = 0;
list_add (&urb_priv->pending, &ohci->pending);
if (data_len)
@@ -672,7 +671,8 @@ static void td_submit_urb (
* we could often reduce the number of TDs here.
*/
case PIPE_ISOCHRONOUS:
- for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
+ for (cnt = urb_priv->td_cnt; cnt < urb->number_of_packets;
+ cnt++) {
int frame = urb->start_frame;
// FIXME scheduling should handle frame counter
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 0d2309ca471e..e84190f25c6b 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -323,8 +323,6 @@ usb_hcd_s3c2410_remove(struct usb_hcd *hcd, struct platform_device *dev)
{
usb_remove_hcd(hcd);
s3c2410_stop_hc(dev);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
}
@@ -353,35 +351,29 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
hcd->rsrc_start = dev->resource[0].start;
hcd->rsrc_len = resource_size(&dev->resource[0]);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- dev_err(&dev->dev, "request_mem_region failed\n");
- retval = -EBUSY;
+ hcd->regs = devm_request_and_ioremap(&dev->dev, &dev->resource[0]);
+ if (!hcd->regs) {
+ dev_err(&dev->dev, "devm_request_and_ioremap failed\n");
+ retval = -ENOMEM;
goto err_put;
}
- clk = clk_get(&dev->dev, "usb-host");
+ clk = devm_clk_get(&dev->dev, "usb-host");
if (IS_ERR(clk)) {
dev_err(&dev->dev, "cannot get usb-host clock\n");
retval = PTR_ERR(clk);
- goto err_mem;
+ goto err_put;
}
- usb_clk = clk_get(&dev->dev, "usb-bus-host");
+ usb_clk = devm_clk_get(&dev->dev, "usb-bus-host");
if (IS_ERR(usb_clk)) {
dev_err(&dev->dev, "cannot get usb-bus-host clock\n");
retval = PTR_ERR(usb_clk);
- goto err_clk;
+ goto err_put;
}
s3c2410_start_hc(dev, hcd);
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- dev_err(&dev->dev, "ioremap failed\n");
- retval = -ENOMEM;
- goto err_ioremap;
- }
-
ohci_hcd_init(hcd_to_ohci(hcd));
retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
@@ -392,14 +384,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
err_ioremap:
s3c2410_stop_hc(dev);
- iounmap(hcd->regs);
- clk_put(usb_clk);
-
- err_clk:
- clk_put(clk);
-
- err_mem:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put:
usb_put_hcd(hcd);
@@ -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
index 76a20c278362..000000000000
--- a/drivers/usb/host/ohci-sh.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- *
- * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <linux/platform_device.h>
-
-static int ohci_sh_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
- ohci_hcd_init(ohci);
- ohci_init(ohci);
- ohci_run(ohci);
- return 0;
-}
-
-static const struct hc_driver ohci_sh_hc_driver = {
- .description = hcd_name,
- .product_desc = "SuperH OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_sh_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_sh_probe(struct platform_device *pdev)
-{
- struct resource *res = NULL;
- struct usb_hcd *hcd = NULL;
- int irq = -1;
- int ret;
-
- if (usb_disabled())
- return -ENODEV;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "platform_get_resource error.\n");
- return -ENODEV;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "platform_get_irq error.\n");
- return -ENODEV;
- }
-
- /* initialize hcd */
- hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name);
- if (!hcd) {
- dev_err(&pdev->dev, "Failed to create hcd\n");
- return -ENOMEM;
- }
-
- hcd->regs = (void __iomem *)res->start;
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (ret != 0) {
- dev_err(&pdev->dev, "Failed to add hcd\n");
- usb_put_hcd(hcd);
- return ret;
- }
-
- return ret;
-}
-
-static int ohci_hcd_sh_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
-
- return 0;
-}
-
-static struct platform_driver ohci_hcd_sh_driver = {
- .probe = ohci_hcd_sh_probe,
- .remove = ohci_hcd_sh_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "sh_ohci",
- .owner = THIS_MODULE,
- },
-};
-
-MODULE_ALIAS("platform:sh_ohci");
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index 5596ac2ba1ca..3b5b908fd47b 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -238,7 +238,7 @@ static int ohci_sm501_resume(struct platform_device *pdev)
ohci->next_statechange = jiffies;
sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
- ohci_finish_controller_resume(hcd);
+ ohci_resume(hcd, false);
return 0;
}
#else
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index fc7305ee3c9c..d607be33c03c 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -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
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index 60c2b0722f2e..2c9ab8f126d4 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -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
index 84201cd1a472..000000000000
--- a/drivers/usb/host/ohci-xls.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * OHCI HCD for Netlogic XLS processors.
- *
- * (C) Copyright 2011 Netlogic Microsystems Inc.
- *
- * Based on ohci-au1xxx.c, and other Linux OHCI drivers.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/platform_device.h>
-#include <linux/signal.h>
-
-static int ohci_xls_probe_internal(const struct hc_driver *driver,
- struct platform_device *dev)
-{
- struct resource *res;
- struct usb_hcd *hcd;
- int retval, irq;
-
- /* Get our IRQ from an earlier registered Platform Resource */
- irq = platform_get_irq(dev, 0);
- if (irq < 0) {
- dev_err(&dev->dev, "Found HC with no IRQ\n");
- return -ENODEV;
- }
-
- /* Get our Memory Handle */
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&dev->dev, "MMIO Handle incorrect!\n");
- return -ENODEV;
- }
-
- hcd = usb_create_hcd(driver, &dev->dev, "XLS");
- if (!hcd) {
- retval = -ENOMEM;
- goto err1;
- }
- hcd->rsrc_start = res->start;
- hcd->rsrc_len = resource_size(res);
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(&dev->dev, "Controller already in use\n");
- retval = -EBUSY;
- goto err2;
- }
-
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
- if (hcd->regs == NULL) {
- dev_dbg(&dev->dev, "error mapping memory\n");
- retval = -EFAULT;
- goto err3;
- }
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval != 0)
- goto err4;
- return retval;
-
-err4:
- iounmap(hcd->regs);
-err3:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err2:
- usb_put_hcd(hcd);
-err1:
- dev_err(&dev->dev, "init fail, %d\n", retval);
- return retval;
-}
-
-static int ohci_xls_reset(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
- ohci_hcd_init(ohci);
- return ohci_init(ohci);
-}
-
-static int __devinit ohci_xls_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci;
- int ret;
-
- ohci = hcd_to_ohci(hcd);
- ret = ohci_run(ohci);
- if (ret < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
- return 0;
-}
-
-static struct hc_driver ohci_xls_hc_driver = {
- .description = hcd_name,
- .product_desc = "XLS OHCI Host Controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
- .irq = ohci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
- .reset = ohci_xls_reset,
- .start = ohci_xls_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
- .get_frame_number = ohci_get_frame,
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-static int ohci_xls_probe(struct platform_device *dev)
-{
- int ret;
-
- pr_debug("In ohci_xls_probe");
- if (usb_disabled())
- return -ENODEV;
- ret = ohci_xls_probe_internal(&ohci_xls_hc_driver, dev);
- return ret;
-}
-
-static int ohci_xls_remove(struct platform_device *dev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(dev);
-
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
- return 0;
-}
-
-static struct platform_driver ohci_xls_driver = {
- .probe = ohci_xls_probe,
- .remove = ohci_xls_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ohci-xls-0",
- .owner = THIS_MODULE,
- },
-};
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index fcc09e5ec0ad..b3eea0ba97a9 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2036,10 +2036,8 @@ static void collect_usb_address_map(struct usb_device *udev, unsigned long *map)
udev->parent->descriptor.bDeviceClass == USB_CLASS_HUB)
map[udev->devnum/32] |= (1 << (udev->devnum % 32));
- usb_hub_for_each_child(udev, chix, childdev) {
- if (childdev)
- collect_usb_address_map(childdev, map);
- }
+ usb_hub_for_each_child(udev, chix, childdev)
+ collect_usb_address_map(childdev, map);
}
/* this function must be called with interrupt disabled */
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index d2c6f5ac4626..15921fd55048 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1256,7 +1256,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
struct uhci_qh *qh)
{
struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */
- int i, frame;
+ int i;
+ unsigned frame, next;
unsigned long destination, status;
struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
@@ -1265,37 +1266,29 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
urb->number_of_packets >= UHCI_NUMFRAMES)
return -EFBIG;
+ uhci_get_current_frame_number(uhci);
+
/* Check the period and figure out the starting frame number */
if (!qh->bandwidth_reserved) {
qh->period = urb->interval;
- if (urb->transfer_flags & URB_ISO_ASAP) {
- qh->phase = -1; /* Find the best phase */
- i = uhci_check_bandwidth(uhci, qh);
- if (i)
- return i;
-
- /* Allow a little time to allocate the TDs */
- uhci_get_current_frame_number(uhci);
- frame = uhci->frame_number + 10;
-
- /* Move forward to the first frame having the
- * correct phase */
- urb->start_frame = frame + ((qh->phase - frame) &
- (qh->period - 1));
- } else {
- i = urb->start_frame - uhci->last_iso_frame;
- if (i <= 0 || i >= UHCI_NUMFRAMES)
- return -EINVAL;
- qh->phase = urb->start_frame & (qh->period - 1);
- i = uhci_check_bandwidth(uhci, qh);
- if (i)
- return i;
- }
+ qh->phase = -1; /* Find the best phase */
+ i = uhci_check_bandwidth(uhci, qh);
+ if (i)
+ return i;
+
+ /* Allow a little time to allocate the TDs */
+ next = uhci->frame_number + 10;
+ frame = qh->phase;
+
+ /* Round up to the first available slot */
+ frame += (next - frame + qh->period - 1) & -qh->period;
} else if (qh->period != urb->interval) {
return -EINVAL; /* Can't change the period */
} else {
+ next = uhci->frame_number + 2;
+
/* Find the next unused frame */
if (list_empty(&qh->queue)) {
frame = qh->iso_frame;
@@ -1308,25 +1301,31 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
lurb->number_of_packets *
lurb->interval;
}
- if (urb->transfer_flags & URB_ISO_ASAP) {
- /* Skip some frames if necessary to insure
- * the start frame is in the future.
+
+ /* Fell behind? */
+ if (uhci_frame_before_eq(frame, next)) {
+
+ /* USB_ISO_ASAP: Round up to the first available slot */
+ if (urb->transfer_flags & URB_ISO_ASAP)
+ frame += (next - frame + qh->period - 1) &
+ -qh->period;
+
+ /*
+ * Not ASAP: Use the next slot in the stream. If
+ * the entire URB falls before the threshold, fail.
*/
- uhci_get_current_frame_number(uhci);
- if (uhci_frame_before_eq(frame, uhci->frame_number)) {
- frame = uhci->frame_number + 1;
- frame += ((qh->phase - frame) &
- (qh->period - 1));
- }
- } /* Otherwise pick up where the last URB leaves off */
- urb->start_frame = frame;
+ else if (!uhci_frame_before_eq(next,
+ frame + (urb->number_of_packets - 1) *
+ qh->period))
+ return -EXDEV;
+ }
}
/* Make sure we won't have to go too far into the future */
if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES,
- urb->start_frame + urb->number_of_packets *
- urb->interval))
+ frame + urb->number_of_packets * urb->interval))
return -EFBIG;
+ urb->start_frame = frame;
status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
diff --git a/drivers/usb/misc/ezusb.c b/drivers/usb/misc/ezusb.c
index 6589268a6515..e712afed947c 100644
--- a/drivers/usb/misc/ezusb.c
+++ b/drivers/usb/misc/ezusb.c
@@ -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");
diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c
index 987116f9efcd..9d13c81754e0 100644
--- a/drivers/usb/phy/tegra_usb_phy.c
+++ b/drivers/usb/phy/tegra_usb_phy.c
@@ -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
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index be845873e23d..381515572235 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -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
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 0616f235bd6b..ce310170829f 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -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;
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 231009af65a3..1d365316960c 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -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
*