Merge 4.2-rc6 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Aug 2015 17:01:33 +0000 (10:01 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Aug 2015 17:01:33 +0000 (10:01 -0700)
We want the USB fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31 files changed:
Documentation/ABI/testing/sysfs-bus-usb
Documentation/usb/power-management.txt
drivers/usb/atm/cxacru.c
drivers/usb/class/usblp.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/sysfs.c
drivers/usb/host/Kconfig
drivers/usb/host/bcma-hcd.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-fsl.h
drivers/usb/host/ehci-platform.c
drivers/usb/host/ehci-st.c
drivers/usb/host/fsl-mph-dr-of.c
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/u132-hcd.c
drivers/usb/host/xhci-dbg.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/ftdi-elan.c
drivers/usb/musb/musb_dsps.c
drivers/usb/phy/phy-keystone.c
drivers/usb/phy/phy-mxs-usb.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/mxuport.c
drivers/usb/storage/transport.c
include/linux/fsl_devices.h
include/linux/usb/hcd.h

index e5cc7633d0131db82951d489b311195967db2db8..864637f25bee49a616865901ed6b0d4daa1791c8 100644 (file)
@@ -114,6 +114,20 @@ Description:
                enabled for the device. Developer can write y/Y/1 or n/N/0 to
                the file to enable/disable the feature.
 
+What:          /sys/bus/usb/devices/.../power/usb3_hardware_lpm
+Date:          June 2015
+Contact:       Kevin Strasser <kevin.strasser@linux.intel.com>
+Description:
+               If CONFIG_PM is set and a USB 3.0 lpm-capable device is plugged
+               in to a xHCI host which supports link PM, it will check if U1
+               and U2 exit latencies have been set in the BOS descriptor; if
+               the check is is passed and the host supports USB3 hardware LPM,
+               USB3 hardware LPM will be enabled for the device and the USB
+               device directory will contain a file named
+               power/usb3_hardware_lpm. The file holds a string value (enable
+               or disable) indicating whether or not USB3 hardware LPM is
+               enabled for the device.
+
 What:          /sys/bus/usb/devices/.../removable
 Date:          February 2012
 Contact:       Matthew Garrett <mjg@redhat.com>
index b5f83911732a4a2af39873db9a851bf6d296dd07..4a15c90bc11d93d362b0397899091d048992a545 100644 (file)
@@ -521,10 +521,10 @@ enabling hardware LPM, the host can automatically put the device into
 lower power state(L1 for usb2.0 devices, or U1/U2 for usb3.0 devices),
 which state device can enter and resume very quickly.
 
-The user interface for controlling USB2 hardware LPM is located in the
+The user interface for controlling hardware LPM is located in the
 power/ subdirectory of each USB device's sysfs directory, that is, in
 /sys/bus/usb/devices/.../power/ where "..." is the device's ID. The
-relevant attribute files is usb2_hardware_lpm.
+relevant attribute files are usb2_hardware_lpm and usb3_hardware_lpm.
 
        power/usb2_hardware_lpm
 
@@ -537,6 +537,17 @@ relevant attribute files is usb2_hardware_lpm.
                can write y/Y/1 or n/N/0 to the file to enable/disable
                USB2 hardware LPM manually. This is for test purpose mainly.
 
+       power/usb3_hardware_lpm
+
+               When a USB 3.0 lpm-capable device is plugged in to a
+               xHCI host which supports link PM, it will check if U1
+               and U2 exit latencies have been set in the BOS
+               descriptor; if the check is is passed and the host
+               supports USB3 hardware LPM, USB3 hardware LPM will be
+               enabled for the device and this file will be created.
+               The file holds a string value (enable or disable)
+               indicating whether or not USB3 hardware LPM is
+               enabled for the device.
 
        USB Port Power Control
        ----------------------
index 813d4d3a51c699a8987c8f95fac0beed20248024..1173f9cbc137ef1b175a84de7d2c8c81219323f5 100644 (file)
@@ -270,6 +270,7 @@ static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf)
 static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf)
 {
        static char *str[] = { "no", "yes" };
+
        if (unlikely(value >= ARRAY_SIZE(str)))
                return snprintf(buf, PAGE_SIZE, "%u\n", value);
        return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
@@ -278,6 +279,7 @@ static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf)
 static ssize_t cxacru_sysfs_showattr_LINK(u32 value, char *buf)
 {
        static char *str[] = { NULL, "not connected", "connected", "lost" };
+
        if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
                return snprintf(buf, PAGE_SIZE, "%u\n", value);
        return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
@@ -702,6 +704,7 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ
        len = ret / 4;
        for (offb = 0; offb < len; ) {
                int l = le32_to_cpu(buf[offb++]);
+
                if (l < 0 || l > stride || l > (len - offb) / 2) {
                        if (printk_ratelimit())
                                usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n",
@@ -732,6 +735,7 @@ cleanup:
 static int cxacru_card_status(struct cxacru_data *instance)
 {
        int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
+
        if (ret < 0) {          /* firmware not loaded */
                usb_dbg(instance->usbatm, "cxacru_adsl_start: CARD_GET_STATUS returned %d\n", ret);
                return ret;
@@ -945,6 +949,7 @@ static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw,
        offb = offd = 0;
        do {
                int l = min_t(int, stride, size - offd);
+
                buf[offb++] = fw;
                buf[offb++] = l;
                buf[offb++] = code1;
@@ -1091,8 +1096,8 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
 {
        const struct firmware *fw, *bp;
        struct cxacru_data *instance = usbatm_instance->driver_data;
-
        int ret = cxacru_find_firmware(instance, "fw", &fw);
+
        if (ret) {
                usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n");
                return ret;
index f38e875a3fb19d10e00773607c3d37fb7dd28b8d..433bbc34a8a481ff15c8070e9917ecf1ec1455e8 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/mutex.h>
 #undef DEBUG
 #include <linux/usb.h>
+#include <linux/usb/ch9.h>
 #include <linux/ratelimit.h>
 
 /*
 #define IOCNR_SOFT_RESET               7
 /* Get device_id string: */
 #define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
-/* The following ioctls were added for http://hpoj.sourceforge.net: */
-/* Get two-int array:
- * [0]=current protocol (1=7/1/1, 2=7/1/2, 3=7/1/3),
- * [1]=supported protocol mask (mask&(1<<n)!=0 means 7/1/n supported): */
+/* The following ioctls were added for http://hpoj.sourceforge.net:
+ * Get two-int array:
+ * [0]=current protocol
+ *     (1=USB_CLASS_PRINTER/1/1, 2=USB_CLASS_PRINTER/1/2,
+ *         3=USB_CLASS_PRINTER/1/3),
+ * [1]=supported protocol mask (mask&(1<<n)!=0 means
+ *     USB_CLASS_PRINTER/1/n supported):
+ */
 #define LPIOC_GET_PROTOCOLS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_PROTOCOLS, len)
-/* Set protocol (arg: 1=7/1/1, 2=7/1/2, 3=7/1/3): */
+/*
+ * Set protocol
+ *     (arg: 1=USB_CLASS_PRINTER/1/1, 2=USB_CLASS_PRINTER/1/2,
+ *         3=USB_CLASS_PRINTER/1/3):
+ */
 #define LPIOC_SET_PROTOCOL _IOC(_IOC_WRITE, 'P', IOCNR_SET_PROTOCOL, 0)
 /* Set channel number (HP Vendor-specific command): */
 #define LPIOC_HP_SET_CHANNEL _IOC(_IOC_WRITE, 'P', IOCNR_HP_SET_CHANNEL, 0)
@@ -146,8 +155,10 @@ struct usblp {
        int                     readcount;              /* Counter for reads */
        int                     ifnum;                  /* Interface number */
        struct usb_interface    *intf;                  /* The interface */
-       /* Alternate-setting numbers and endpoints for each protocol
-        * (7/1/{index=1,2,3}) that the device supports: */
+       /*
+        * Alternate-setting numbers and endpoints for each protocol
+        * (USB_CLASS_PRINTER/1/{index=1,2,3}) that the device supports:
+        */
        struct {
                int                             alt_setting;
                struct usb_endpoint_descriptor  *epwrite;
@@ -1206,19 +1217,23 @@ abort_ret:
  * but our requirements are too intricate for simple match to handle.
  *
  * The "proto_bias" option may be used to specify the preferred protocol
- * for all USB printers (1=7/1/1, 2=7/1/2, 3=7/1/3).  If the device
- * supports the preferred protocol, then we bind to it.
+ * for all USB printers (1=USB_CLASS_PRINTER/1/1, 2=USB_CLASS_PRINTER/1/2,
+ * 3=USB_CLASS_PRINTER/1/3).  If the device supports the preferred protocol,
+ * then we bind to it.
  *
- * The best interface for us is 7/1/2, because it is compatible
- * with a stream of characters. If we find it, we bind to it.
+ * The best interface for us is USB_CLASS_PRINTER/1/2, because it
+ * is compatible with a stream of characters. If we find it, we bind to it.
  *
  * Note that the people from hpoj.sourceforge.net need to be able to
- * bind to 7/1/3 (MLC/1284.4), so we provide them ioctls for this purpose.
+ * bind to USB_CLASS_PRINTER/1/3 (MLC/1284.4), so we provide them ioctls
+ * for this purpose.
  *
- * Failing 7/1/2, we look for 7/1/3, even though it's probably not
- * stream-compatible, because this matches the behaviour of the old code.
+ * Failing USB_CLASS_PRINTER/1/2, we look for USB_CLASS_PRINTER/1/3,
+ * even though it's probably not stream-compatible, because this matches
+ * the behaviour of the old code.
  *
- * If nothing else, we bind to 7/1/1 - the unidirectional interface.
+ * If nothing else, we bind to USB_CLASS_PRINTER/1/1
+ * - the unidirectional interface.
  */
 static int usblp_select_alts(struct usblp *usblp)
 {
@@ -1236,7 +1251,8 @@ static int usblp_select_alts(struct usblp *usblp)
        for (i = 0; i < if_alt->num_altsetting; i++) {
                ifd = &if_alt->altsetting[i];
 
-               if (ifd->desc.bInterfaceClass != 7 || ifd->desc.bInterfaceSubClass != 1)
+               if (ifd->desc.bInterfaceClass != USB_CLASS_PRINTER ||
+                   ifd->desc.bInterfaceSubClass != 1)
                        if (!(usblp->quirks & USBLP_QUIRK_BAD_CLASS))
                                continue;
 
@@ -1262,8 +1278,10 @@ static int usblp_select_alts(struct usblp *usblp)
                if (!epwrite || (ifd->desc.bInterfaceProtocol > 1 && !epread))
                        continue;
 
-               /* Turn off reads for 7/1/1 (unidirectional) interfaces
-                * and buggy bidirectional printers. */
+               /*
+                * Turn off reads for USB_CLASS_PRINTER/1/1 (unidirectional)
+                * interfaces and buggy bidirectional printers.
+                */
                if (ifd->desc.bInterfaceProtocol == 1) {
                        epread = NULL;
                } else if (usblp->quirks & USBLP_QUIRK_BIDIR) {
@@ -1406,12 +1424,12 @@ static int usblp_resume(struct usb_interface *intf)
 }
 
 static const struct usb_device_id usblp_ids[] = {
-       { USB_DEVICE_INFO(7, 1, 1) },
-       { USB_DEVICE_INFO(7, 1, 2) },
-       { USB_DEVICE_INFO(7, 1, 3) },
-       { USB_INTERFACE_INFO(7, 1, 1) },
-       { USB_INTERFACE_INFO(7, 1, 2) },
-       { USB_INTERFACE_INFO(7, 1, 3) },
+       { USB_DEVICE_INFO(USB_CLASS_PRINTER, 1, 1) },
+       { USB_DEVICE_INFO(USB_CLASS_PRINTER, 1, 2) },
+       { USB_DEVICE_INFO(USB_CLASS_PRINTER, 1, 3) },
+       { USB_INTERFACE_INFO(USB_CLASS_PRINTER, 1, 1) },
+       { USB_INTERFACE_INFO(USB_CLASS_PRINTER, 1, 2) },
+       { USB_INTERFACE_INFO(USB_CLASS_PRINTER, 1, 3) },
        { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
        { }                                             /* Terminating entry */
 };
index 986abde076831921bf33f075a54fa8500630dd58..38ae877c46e3124eb07c2a46ddd33bc66ac54d93 100644 (file)
@@ -103,7 +103,7 @@ MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic");
 #define snoop(dev, format, arg...)                             \
        do {                                                    \
                if (usbfs_snoop)                                \
-                       dev_info(dev , format , ## arg);        \
+                       dev_info(dev, format, ## arg);          \
        } while (0)
 
 enum snoop_when {
@@ -1082,7 +1082,8 @@ static int proc_bulk(struct usb_dev_state *ps, void __user *arg)
        ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb));
        if (ret)
                return ret;
-       if (!(tbuf = kmalloc(len1, GFP_KERNEL))) {
+       tbuf = kmalloc(len1, GFP_KERNEL);
+       if (!tbuf) {
                ret = -ENOMEM;
                goto done;
        }
@@ -1224,7 +1225,8 @@ static int proc_setintf(struct usb_dev_state *ps, void __user *arg)
 
        if (copy_from_user(&setintf, arg, sizeof(setintf)))
                return -EFAULT;
-       if ((ret = checkintf(ps, setintf.interface)))
+       ret = checkintf(ps, setintf.interface);
+       if (ret)
                return ret;
 
        destroy_async_on_interface(ps, setintf.interface);
@@ -1319,7 +1321,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
        is_in = (uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0;
 
        u = 0;
-       switch(uurb->type) {
+       switch (uurb->type) {
        case USBDEVFS_URB_TYPE_CONTROL:
                if (!usb_endpoint_xfer_control(&ep->desc))
                        return -EINVAL;
@@ -1393,7 +1395,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
                number_of_packets = uurb->number_of_packets;
                isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) *
                                   number_of_packets;
-               if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
+               isopkt = kmalloc(isofrmlen, GFP_KERNEL);
+               if (!isopkt)
                        return -ENOMEM;
                if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) {
                        ret = -EFAULT;
@@ -1904,7 +1907,8 @@ static int proc_releaseinterface(struct usb_dev_state *ps, void __user *arg)
 
        if (get_user(ifnum, (unsigned int __user *)arg))
                return -EFAULT;
-       if ((ret = releaseintf(ps, ifnum)) < 0)
+       ret = releaseintf(ps, ifnum);
+       if (ret < 0)
                return ret;
        destroy_async_on_interface (ps, ifnum);
        return 0;
@@ -1919,7 +1923,8 @@ static int proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl)
        struct usb_driver       *driver = NULL;
 
        /* alloc buffer */
-       if ((size = _IOC_SIZE(ctl->ioctl_code)) > 0) {
+       size = _IOC_SIZE(ctl->ioctl_code);
+       if (size > 0) {
                buf = kmalloc(size, GFP_KERNEL);
                if (buf == NULL)
                        return -ENOMEM;
index 818369afff63f3a6bc53059fc107937f0d6c0b42..6b5063e7943fac720a266478d79b04a352d51e41 100644 (file)
@@ -160,6 +160,7 @@ static ssize_t remove_id_store(struct device_driver *driver, const char *buf,
        spin_lock(&usb_driver->dynids.lock);
        list_for_each_entry_safe(dynid, n, &usb_driver->dynids.list, node) {
                struct usb_device_id *id = &dynid->id;
+
                if ((id->idVendor == idVendor) &&
                    (id->idProduct == idProduct)) {
                        list_del(&dynid->node);
index cbcd0920fb5121ba44bd7c87de9a3b3fdd9f51d6..4d64e5c499e194d3c364543fca9f9e76442684b2 100644 (file)
@@ -2686,12 +2686,14 @@ int usb_add_hcd(struct usb_hcd *hcd,
         * bottom up so that hcds can customize the root hubs before hub_wq
         * starts talking to them.  (Note, bus id is assigned early too.)
         */
-       if ((retval = hcd_buffer_create(hcd)) != 0) {
+       retval = hcd_buffer_create(hcd);
+       if (retval != 0) {
                dev_dbg(hcd->self.controller, "pool alloc failed\n");
                goto err_create_buf;
        }
 
-       if ((retval = usb_register_bus(&hcd->self)) < 0)
+       retval = usb_register_bus(&hcd->self);
+       if (retval < 0)
                goto err_register_bus;
 
        rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
@@ -2737,9 +2739,13 @@ int usb_add_hcd(struct usb_hcd *hcd,
        /* "reset" is misnamed; its role is now one-time init. the controller
         * should already have been reset (and boot firmware kicked off etc).
         */
-       if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
-               dev_err(hcd->self.controller, "can't setup: %d\n", retval);
-               goto err_hcd_driver_setup;
+       if (hcd->driver->reset) {
+               retval = hcd->driver->reset(hcd);
+               if (retval < 0) {
+                       dev_err(hcd->self.controller, "can't setup: %d\n",
+                                       retval);
+                       goto err_hcd_driver_setup;
+               }
        }
        hcd->rh_pollable = 1;
 
@@ -2769,7 +2775,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
        }
 
        /* starting here, usbcore will pay attention to this root hub */
-       if ((retval = register_root_hub(hcd)) != 0)
+       retval = register_root_hub(hcd);
+       if (retval != 0)
                goto err_register_root_hub;
 
        retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
index 73dfa194160b78fba6bec233b667b00bceac6cb1..a0b22be1509d640bf85961ea0580819f2b4ee233 100644 (file)
@@ -50,8 +50,8 @@ DEFINE_MUTEX(usb_port_peer_mutex);
 
 /* cycle leds on hubs that aren't blinking for attention */
 static bool blinkenlights = 0;
-module_param (blinkenlights, bool, S_IRUGO);
-MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
+module_param(blinkenlights, bool, S_IRUGO);
+MODULE_PARM_DESC(blinkenlights, "true to cycle leds on hubs");
 
 /*
  * Device SATA8000 FW1.0 from DATAST0R Technology Corp requires about
@@ -439,7 +439,7 @@ static void set_port_led(struct usb_hub *hub, int port1, int selector)
 
 #define        LED_CYCLE_PERIOD        ((2*HZ)/3)
 
-static void led_work (struct work_struct *work)
+static void led_work(struct work_struct *work)
 {
        struct usb_hub          *hub =
                container_of(work, struct usb_hub, leds.work);
@@ -646,7 +646,7 @@ static void hub_irq(struct urb *urb)
 
        default:                /* presumably an error */
                /* Cause a hub reset after 10 consecutive errors */
-               dev_dbg (hub->intfdev, "transfer --> %d\n", status);
+               dev_dbg(hub->intfdev, "transfer --> %d\n", status);
                if ((++hub->nerrors < 10) || hub->error)
                        goto resubmit;
                hub->error = status;
@@ -671,14 +671,14 @@ resubmit:
        if (hub->quiescing)
                return;
 
-       if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0
+       if ((status = usb_submit_urb(hub->urb, GFP_ATOMIC)) != 0
                        && status != -ENODEV && status != -EPERM)
-               dev_err (hub->intfdev, "resubmit --> %d\n", status);
+               dev_err(hub->intfdev, "resubmit --> %d\n", status);
 }
 
 /* USB 2.0 spec Section 11.24.2.3 */
 static inline int
-hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
+hub_clear_tt_buffer(struct usb_device *hdev, u16 devinfo, u16 tt)
 {
        /* Need to clear both directions for control ep */
        if (((devinfo >> 11) & USB_ENDPOINT_XFERTYPE_MASK) ==
@@ -706,7 +706,7 @@ static void hub_tt_work(struct work_struct *work)
                container_of(work, struct usb_hub, tt.clear_work);
        unsigned long           flags;
 
-       spin_lock_irqsave (&hub->tt.lock, flags);
+       spin_lock_irqsave(&hub->tt.lock, flags);
        while (!list_empty(&hub->tt.clear_list)) {
                struct list_head        *next;
                struct usb_tt_clear     *clear;
@@ -715,14 +715,14 @@ static void hub_tt_work(struct work_struct *work)
                int                     status;
 
                next = hub->tt.clear_list.next;
-               clear = list_entry (next, struct usb_tt_clear, clear_list);
-               list_del (&clear->clear_list);
+               clear = list_entry(next, struct usb_tt_clear, clear_list);
+               list_del(&clear->clear_list);
 
                /* drop lock so HCD can concurrently report other TT errors */
-               spin_unlock_irqrestore (&hub->tt.lock, flags);
-               status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
+               spin_unlock_irqrestore(&hub->tt.lock, flags);
+               status = hub_clear_tt_buffer(hdev, clear->devinfo, clear->tt);
                if (status && status != -ENODEV)
-                       dev_err (&hdev->dev,
+                       dev_err(&hdev->dev,
                                "clear tt %d (%04x) error %d\n",
                                clear->tt, clear->devinfo, status);
 
@@ -734,7 +734,7 @@ static void hub_tt_work(struct work_struct *work)
                kfree(clear);
                spin_lock_irqsave(&hub->tt.lock, flags);
        }
-       spin_unlock_irqrestore (&hub->tt.lock, flags);
+       spin_unlock_irqrestore(&hub->tt.lock, flags);
 }
 
 /**
@@ -797,7 +797,7 @@ int usb_hub_clear_tt_buffer(struct urb *urb)
         */
        clear = kmalloc(sizeof *clear, GFP_ATOMIC);
        if (clear == NULL) {
-               dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
+               dev_err(&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
                /* FIXME recover somehow ... RESET_TT? */
                return -ENOMEM;
        }
@@ -806,10 +806,10 @@ int usb_hub_clear_tt_buffer(struct urb *urb)
        clear->tt = tt->multi ? udev->ttport : 1;
        clear->devinfo = usb_pipeendpoint (pipe);
        clear->devinfo |= udev->devnum << 4;
-       clear->devinfo |= usb_pipecontrol (pipe)
+       clear->devinfo |= usb_pipecontrol(pipe)
                        ? (USB_ENDPOINT_XFER_CONTROL << 11)
                        : (USB_ENDPOINT_XFER_BULK << 11);
-       if (usb_pipein (pipe))
+       if (usb_pipein(pipe))
                clear->devinfo |= 1 << 15;
 
        /* info for completion callback */
@@ -817,10 +817,10 @@ int usb_hub_clear_tt_buffer(struct urb *urb)
        clear->ep = urb->ep;
 
        /* tell keventd to clear state for this TT */
-       spin_lock_irqsave (&tt->lock, flags);
-       list_add_tail (&clear->clear_list, &tt->clear_list);
+       spin_lock_irqsave(&tt->lock, flags);
+       list_add_tail(&clear->clear_list, &tt->clear_list);
        schedule_work(&tt->clear_work);
-       spin_unlock_irqrestore (&tt->lock, flags);
+       spin_unlock_irqrestore(&tt->lock, flags);
        return 0;
 }
 EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer);
@@ -3950,6 +3950,8 @@ int usb_disable_lpm(struct usb_device *udev)
        if (usb_disable_link_state(hcd, udev, USB3_LPM_U2))
                goto enable_lpm;
 
+       udev->usb3_lpm_enabled = 0;
+
        return 0;
 
 enable_lpm:
@@ -4007,6 +4009,8 @@ void usb_enable_lpm(struct usb_device *udev)
 
        usb_enable_link_state(hcd, udev, USB3_LPM_U1);
        usb_enable_link_state(hcd, udev, USB3_LPM_U2);
+
+       udev->usb3_lpm_enabled = 1;
 }
 EXPORT_SYMBOL_GPL(usb_enable_lpm);
 
index d26973844a4dea0186f759de848c3baf2442088f..cfc68c11c3f565d27bfb9898a9e0d18e7a5d58e6 100644 (file)
@@ -531,6 +531,25 @@ static ssize_t usb2_lpm_besl_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(usb2_lpm_besl);
 
+static ssize_t usb3_hardware_lpm_show(struct device *dev,
+                                     struct device_attribute *attr, char *buf)
+{
+       struct usb_device *udev = to_usb_device(dev);
+       const char *p;
+
+       usb_lock_device(udev);
+
+       if (udev->usb3_lpm_enabled)
+               p = "enabled";
+       else
+               p = "disabled";
+
+       usb_unlock_device(udev);
+
+       return sprintf(buf, "%s\n", p);
+}
+static DEVICE_ATTR_RO(usb3_hardware_lpm);
+
 static struct attribute *usb2_hardware_lpm_attr[] = {
        &dev_attr_usb2_hardware_lpm.attr,
        &dev_attr_usb2_lpm_l1_timeout.attr,
@@ -542,6 +561,15 @@ static struct attribute_group usb2_hardware_lpm_attr_group = {
        .attrs  = usb2_hardware_lpm_attr,
 };
 
+static struct attribute *usb3_hardware_lpm_attr[] = {
+       &dev_attr_usb3_hardware_lpm.attr,
+       NULL,
+};
+static struct attribute_group usb3_hardware_lpm_attr_group = {
+       .name   = power_group_name,
+       .attrs  = usb3_hardware_lpm_attr,
+};
+
 static struct attribute *power_attrs[] = {
        &dev_attr_autosuspend.attr,
        &dev_attr_level.attr,
@@ -564,6 +592,9 @@ static int add_power_attributes(struct device *dev)
                if (udev->usb2_hw_lpm_capable == 1)
                        rc = sysfs_merge_group(&dev->kobj,
                                        &usb2_hardware_lpm_attr_group);
+               if (udev->lpm_capable == 1)
+                       rc = sysfs_merge_group(&dev->kobj,
+                                       &usb3_hardware_lpm_attr_group);
        }
 
        return rc;
index 8afc3c1efdab10325ba7225483e6dd47d3abd5b6..5f0567927f1f44bd1e9e60d789aec05e5ac5218a 100644 (file)
@@ -32,7 +32,14 @@ config USB_XHCI_PCI
        default y
 
 config USB_XHCI_PLATFORM
-       tristate
+       tristate "Generic xHCI driver for a platform device"
+       ---help---
+         Adds an xHCI host driver for a generic platform device, which
+         provides a memory space and an irq.
+         It is also a prerequisite for platform specific drivers that
+         implement some extra quirks.
+
+         If unsure, say N.
 
 config USB_XHCI_MVEBU
        tristate "xHCI support for Marvell Armada 375/38x"
index 526cfab41d5f7022b4c62c3754a5eb69a30240f3..5398e3d42822cf41f566885a3ffa2ee2d757b98f 100644 (file)
@@ -2,7 +2,8 @@
  * Broadcom specific Advanced Microcontroller Bus
  * Broadcom USB-core driver (BCMA bus glue)
  *
- * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2011-2015 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2015 Felix Fietkau <nbd@openwrt.org>
  *
  * Based on ssb-ohci driver
  * Copyright 2007 Michael Buesch <m@bues.ch>
@@ -23,6 +24,8 @@
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/usb/ehci_pdriver.h>
 #include <linux/usb/ohci_pdriver.h>
 
@@ -88,7 +91,7 @@ static void bcma_hcd_4716wa(struct bcma_device *dev)
 }
 
 /* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
-static void bcma_hcd_init_chip(struct bcma_device *dev)
+static void bcma_hcd_init_chip_mips(struct bcma_device *dev)
 {
        u32 tmp;
 
@@ -159,6 +162,87 @@ static void bcma_hcd_init_chip(struct bcma_device *dev)
        }
 }
 
+static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev)
+{
+       struct bcma_device *arm_core;
+       void __iomem *dmu;
+
+       arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9);
+       if (!arm_core) {
+               dev_err(&dev->dev, "can not find ARM Cortex A9 ihost core\n");
+               return;
+       }
+
+       dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
+       if (!dmu) {
+               dev_err(&dev->dev, "can not map ARM Cortex A9 ihost core\n");
+               return;
+       }
+
+       /* Unlock DMU PLL settings */
+       iowrite32(0x0000ea68, dmu + 0x180);
+
+       /* Write USB 2.0 PLL control setting */
+       iowrite32(0x00dd10c3, dmu + 0x164);
+
+       /* Lock DMU PLL settings */
+       iowrite32(0x00000000, dmu + 0x180);
+
+       iounmap(dmu);
+}
+
+static void bcma_hcd_init_chip_arm_hc(struct bcma_device *dev)
+{
+       u32 val;
+
+       /*
+        * Delay after PHY initialized to ensure HC is ready to be configured
+        */
+       usleep_range(1000, 2000);
+
+       /* Set packet buffer OUT threshold */
+       val = bcma_read32(dev, 0x94);
+       val &= 0xffff;
+       val |= 0x80 << 16;
+       bcma_write32(dev, 0x94, val);
+
+       /* Enable break memory transfer */
+       val = bcma_read32(dev, 0x9c);
+       val |= 1;
+       bcma_write32(dev, 0x9c, val);
+}
+
+static void bcma_hcd_init_chip_arm(struct bcma_device *dev)
+{
+       bcma_core_enable(dev, 0);
+
+       if (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4707 ||
+           dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM53018) {
+               if (dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4707 ||
+                   dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4708)
+                       bcma_hcd_init_chip_arm_phy(dev);
+
+               bcma_hcd_init_chip_arm_hc(dev);
+       }
+}
+
+static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
+{
+       int gpio;
+
+       gpio = of_get_named_gpio(dev->dev.of_node, "vcc-gpio", 0);
+       if (!gpio_is_valid(gpio))
+               return;
+
+       if (val) {
+               gpio_request(gpio, "bcma-hcd-gpio");
+               gpio_set_value(gpio, 1);
+       } else {
+               gpio_set_value(gpio, 0);
+               gpio_free(gpio);
+       }
+}
+
 static const struct usb_ehci_pdata ehci_pdata = {
 };
 
@@ -169,7 +253,7 @@ static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, boo
 {
        struct platform_device *hci_dev;
        struct resource hci_res[2];
-       int ret = -ENOMEM;
+       int ret;
 
        memset(hci_res, 0, sizeof(hci_res));
 
@@ -183,7 +267,7 @@ static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, boo
        hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
                                        "ehci-platform" , 0);
        if (!hci_dev)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        hci_dev->dev.parent = &dev->dev;
        hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
@@ -214,39 +298,45 @@ err_alloc:
 static int bcma_hcd_probe(struct bcma_device *dev)
 {
        int err;
-       u16 chipid_top;
        u32 ohci_addr;
        struct bcma_hcd_device *usb_dev;
        struct bcma_chipinfo *chipinfo;
 
        chipinfo = &dev->bus->chipinfo;
-       /* USBcores are only connected on embedded devices. */
-       chipid_top = (chipinfo->id & 0xFF00);
-       if (chipid_top != 0x4700 && chipid_top != 0x5300)
-               return -ENODEV;
 
        /* TODO: Probably need checks here; is the core connected? */
 
        if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))
                return -EOPNOTSUPP;
 
-       usb_dev = kzalloc(sizeof(struct bcma_hcd_device), GFP_KERNEL);
+       usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device),
+                              GFP_KERNEL);
        if (!usb_dev)
                return -ENOMEM;
 
-       bcma_hcd_init_chip(dev);
+       bcma_hci_platform_power_gpio(dev, true);
+
+       switch (dev->id.id) {
+       case BCMA_CORE_NS_USB20:
+               bcma_hcd_init_chip_arm(dev);
+               break;
+       case BCMA_CORE_USB20_HOST:
+               bcma_hcd_init_chip_mips(dev);
+               break;
+       default:
+               return -ENODEV;
+       }
 
        /* In AI chips EHCI is addrspace 0, OHCI is 1 */
        ohci_addr = dev->addr_s[0];
-       if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
+       if ((chipinfo->id == BCMA_CHIP_ID_BCM5357 ||
+            chipinfo->id == BCMA_CHIP_ID_BCM4749)
            && chipinfo->rev == 0)
                ohci_addr = 0x18009000;
 
        usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
-       if (IS_ERR(usb_dev->ohci_dev)) {
-               err = PTR_ERR(usb_dev->ohci_dev);
-               goto err_free_usb_dev;
-       }
+       if (IS_ERR(usb_dev->ohci_dev))
+               return PTR_ERR(usb_dev->ohci_dev);
 
        usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
        if (IS_ERR(usb_dev->ehci_dev)) {
@@ -259,8 +349,6 @@ static int bcma_hcd_probe(struct bcma_device *dev)
 
 err_unregister_ohci_dev:
        platform_device_unregister(usb_dev->ohci_dev);
-err_free_usb_dev:
-       kfree(usb_dev);
        return err;
 }
 
@@ -280,6 +368,7 @@ static void bcma_hcd_remove(struct bcma_device *dev)
 
 static void bcma_hcd_shutdown(struct bcma_device *dev)
 {
+       bcma_hci_platform_power_gpio(dev, false);
        bcma_core_disable(dev, 0);
 }
 
@@ -287,6 +376,7 @@ static void bcma_hcd_shutdown(struct bcma_device *dev)
 
 static int bcma_hcd_suspend(struct bcma_device *dev)
 {
+       bcma_hci_platform_power_gpio(dev, false);
        bcma_core_disable(dev, 0);
 
        return 0;
@@ -294,6 +384,7 @@ static int bcma_hcd_suspend(struct bcma_device *dev)
 
 static int bcma_hcd_resume(struct bcma_device *dev)
 {
+       bcma_hci_platform_power_gpio(dev, true);
        bcma_core_enable(dev, 0);
 
        return 0;
@@ -306,6 +397,7 @@ static int bcma_hcd_resume(struct bcma_device *dev)
 
 static const struct bcma_device_id bcma_hcd_table[] = {
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
        {},
 };
 MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
index 5352e74b92e2112c273c4e0a2c43387a8bd0a105..202dafb7d0cb78897ad2404a50706475d30193d1 100644 (file)
@@ -127,7 +127,18 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
 
        /* Enable USB controller, 83xx or 8536 */
        if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6)
-               setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);
+               clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL,
+                               CONTROL_REGISTER_W1C_MASK, 0x4);
+
+       /*
+        * Enable UTMI phy and program PTS field in UTMI mode before asserting
+        * controller reset for USB Controller version 2.5
+        */
+       if (pdata->has_fsl_erratum_a007792) {
+               clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL,
+                               CONTROL_REGISTER_W1C_MASK, CTRL_UTMI_PHY_EN);
+               writel(PORT_PTS_UTMI, hcd->regs + FSL_SOC_USB_PORTSC1);
+       }
 
        /* Don't need to set host mode here. It will be done by tdi_reset() */
 
@@ -191,9 +202,11 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
        case FSL_USB2_PHY_ULPI:
                if (pdata->have_sysif_regs && pdata->controller_ver) {
                        /* controller version 1.6 or above */
-                       clrbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN);
-                       setbits32(non_ehci + FSL_SOC_USB_CTRL,
-                               ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN);
+                       clrbits32(non_ehci + FSL_SOC_USB_CTRL,
+                                 CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN);
+                       clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL,
+                                       CONTROL_REGISTER_W1C_MASK,
+                                       ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN);
                }
                portsc |= PORT_PTS_ULPI;
                break;
@@ -204,30 +217,33 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
                portsc |= PORT_PTS_PTW;
                /* fall through */
        case FSL_USB2_PHY_UTMI:
+       case FSL_USB2_PHY_UTMI_DUAL:
                if (pdata->have_sysif_regs && pdata->controller_ver) {
                        /* controller version 1.6 or above */
-                       setbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN);
+                       clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL,
+                                       CONTROL_REGISTER_W1C_MASK, UTMI_PHY_EN);
                        mdelay(FSL_UTMI_PHY_DLY);  /* Delay for UTMI PHY CLK to
                                                become stable - 10ms*/
                }
                /* enable UTMI PHY */
                if (pdata->have_sysif_regs)
-                       setbits32(non_ehci + FSL_SOC_USB_CTRL,
-                                 CTRL_UTMI_PHY_EN);
+                       clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL,
+                                       CONTROL_REGISTER_W1C_MASK,
+                                       CTRL_UTMI_PHY_EN);
                portsc |= PORT_PTS_UTMI;
                break;
        case FSL_USB2_PHY_NONE:
                break;
        }
 
-       if (pdata->have_sysif_regs &&
-           pdata->controller_ver > FSL_USB_VER_1_6 &&
-           (phy_mode == FSL_USB2_PHY_ULPI)) {
-               /* check PHY_CLK_VALID to get phy clk valid */
-               if (!(spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) &
-                               PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0) ||
-                               in_be32(non_ehci + FSL_SOC_USB_PRICTRL))) {
-                       dev_warn(hcd->self.controller, "USB PHY clock invalid\n");
+       /*
+        * check PHY_CLK_VALID to determine phy clock presence before writing
+        * to portsc
+        */
+       if (pdata->check_phy_clk_valid) {
+               if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) {
+                       dev_warn(hcd->self.controller,
+                                "USB PHY clock invalid\n");
                        return -EINVAL;
                }
        }
@@ -235,7 +251,8 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
        ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
 
        if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs)
-               setbits32(non_ehci + FSL_SOC_USB_CTRL, USB_CTRL_USB_EN);
+               clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL,
+                               CONTROL_REGISTER_W1C_MASK, USB_CTRL_USB_EN);
 
        return 0;
 }
index dbd292e9f0a7d5a7a31b9a2dcb1bf968b2ed7fa4..1a8a60a57cf2719a032699179583ea3aaae07bac 100644 (file)
@@ -52,6 +52,7 @@
 #define SNOOP_SIZE_2GB         0x1e
 
 /* control Register Bit Masks */
+#define CONTROL_REGISTER_W1C_MASK       0x00020000  /* W1C: PHY_CLK_VALID */
 #define ULPI_INT_EN             (1<<0)
 #define WU_INT_EN               (1<<1)
 #define USB_CTRL_USB_EN         (1<<2)
index 2593def13cea09c1a37210c6780c8752229b4f60..5c3c0859868251233c7672baf9f2ea01c5b82364 100644 (file)
@@ -45,6 +45,7 @@ struct ehci_platform_priv {
        struct reset_control *rst;
        struct phy **phys;
        int num_phys;
+       bool reset_on_resume;
 };
 
 static const char hcd_name[] = "ehci-platform";
@@ -56,7 +57,6 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
        int retval;
 
-       hcd->has_tt = pdata->has_tt;
        ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
 
        if (pdata->pre_setup) {
@@ -193,11 +193,11 @@ static int ehci_platform_probe(struct platform_device *dev)
 
                if (of_property_read_bool(dev->dev.of_node,
                                          "needs-reset-on-resume"))
-                       pdata->reset_on_resume = 1;
+                       priv->reset_on_resume = true;
 
                if (of_property_read_bool(dev->dev.of_node,
                                          "has-transaction-translator"))
-                       pdata->has_tt = 1;
+                       hcd->has_tt = 1;
 
                priv->num_phys = of_count_phandle_with_args(dev->dev.of_node,
                                "phys", "#phy-cells");
@@ -247,6 +247,10 @@ static int ehci_platform_probe(struct platform_device *dev)
                ehci->big_endian_desc = 1;
        if (pdata->big_endian_mmio)
                ehci->big_endian_mmio = 1;
+       if (pdata->has_tt)
+               hcd->has_tt = 1;
+       if (pdata->reset_on_resume)
+               priv->reset_on_resume = true;
 
 #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
        if (ehci->big_endian_mmio) {
@@ -359,6 +363,7 @@ static int ehci_platform_resume(struct device *dev)
        struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
        struct platform_device *pdev =
                container_of(dev, struct platform_device, dev);
+       struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
 
        if (pdata->power_on) {
                int err = pdata->power_on(pdev);
@@ -366,7 +371,7 @@ static int ehci_platform_resume(struct device *dev)
                        return err;
        }
 
-       ehci_resume(hcd, pdata->reset_on_resume);
+       ehci_resume(hcd, priv->reset_on_resume);
        return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
index 7e4bd39cf757eff2f07e68b4c7a5766fac57f89b..b7c5cfa37a83501f8430837cab16fdf19b370c13 100644 (file)
@@ -54,7 +54,6 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
        struct platform_device *pdev = to_platform_device(hcd->self.controller);
        struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-       int retval;
        u32 threshold;
 
        /* Set EHCI packet buffer IN/OUT threshold to 128 bytes */
@@ -62,11 +61,7 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
        writel(threshold, hcd->regs + AHB2STBUS_INSREG01);
 
        ehci->caps = hcd->regs + pdata->caps_offset;
-       retval = ehci_setup(hcd);
-       if (retval)
-               return retval;
-
-       return 0;
+       return ehci_setup(hcd);
 }
 
 static int st_ehci_platform_power_on(struct platform_device *dev)
index 5e0d600352163ae58e8351978de9e39ad61aa63f..9f731413ab3edd7f25ab139e39409c9f2c63dc61 100644 (file)
@@ -69,6 +69,8 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
                return FSL_USB2_PHY_UTMI;
        if (!strcasecmp(phy_type, "utmi_wide"))
                return FSL_USB2_PHY_UTMI_WIDE;
+       if (!strcasecmp(phy_type, "utmi_dual"))
+               return FSL_USB2_PHY_UTMI_DUAL;
        if (!strcasecmp(phy_type, "serial"))
                return FSL_USB2_PHY_SERIAL;
 
@@ -119,9 +121,9 @@ error:
 
 static const struct of_device_id fsl_usb2_mph_dr_of_match[];
 
-static int usb_get_ver_info(struct device_node *np)
+static enum fsl_usb2_controller_ver usb_get_ver_info(struct device_node *np)
 {
-       int ver = -1;
+       enum fsl_usb2_controller_ver ver = FSL_USB_VER_NONE;
 
        /*
         * returns 1 for usb controller version 1.6
@@ -142,7 +144,7 @@ static int usb_get_ver_info(struct device_node *np)
                else /* for previous controller versions */
                        ver = FSL_USB_VER_OLD;
 
-               if (ver > -1)
+               if (ver > FSL_USB_VER_NONE)
                        return ver;
        }
 
@@ -214,8 +216,23 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
        pdata->phy_mode = determine_usb_phy(prop);
        pdata->controller_ver = usb_get_ver_info(np);
 
+       /* Activate Erratum by reading property in device tree */
+       if (of_get_property(np, "fsl,usb-erratum-a007792", NULL))
+               pdata->has_fsl_erratum_a007792 = 1;
+       else
+               pdata->has_fsl_erratum_a007792 = 0;
+
+       /*
+        * Determine whether phy_clk_valid needs to be checked
+        * by reading property in device tree
+        */
+       if (of_get_property(np, "phy-clk-valid", NULL))
+               pdata->check_phy_clk_valid = 1;
+       else
+               pdata->check_phy_clk_valid = 0;
+
        if (pdata->have_sysif_regs) {
-               if (pdata->controller_ver < 0) {
+               if (pdata->controller_ver == FSL_USB_VER_NONE) {
                        dev_warn(&ofdev->dev, "Could not get controller version\n");
                        return -ENODEV;
                }
index 6352f54e65a1d9359f999a26aa6f12cea08f877d..fe3bd1cb8b6bd9dcd82071fb9c98a0ae66fc1836 100644 (file)
@@ -2670,7 +2670,6 @@ static int oxu_hcd_init(struct usb_hcd *hcd)
 static int oxu_reset(struct usb_hcd *hcd)
 {
        struct oxu_hcd *oxu = hcd_to_oxu(hcd);
-       int ret;
 
        spin_lock_init(&oxu->mem_lock);
        INIT_LIST_HEAD(&oxu->urb_list);
@@ -2696,11 +2695,7 @@ static int oxu_reset(struct usb_hcd *hcd)
        oxu->hcs_params = readl(&oxu->caps->hcs_params);
        oxu->sbrn = 0x20;
 
-       ret = oxu_hcd_init(hcd);
-       if (ret)
-               return ret;
-
-       return 0;
+       return oxu_hcd_init(hcd);
 }
 
 static int oxu_run(struct usb_hcd *hcd)
index d51687780b61a5428c8cb2238931d63ac9690bdd..a67bd509033097cfc156f84605f43f3617b951d8 100644 (file)
@@ -1542,11 +1542,8 @@ static int u132_periodic_reinit(struct u132 *u132)
                (fit ^ FIT) | u132->hc_fminterval);
        if (retval)
                return retval;
-       retval = u132_write_pcimem(u132, periodicstart,
-               ((9 * fi) / 10) & 0x3fff);
-       if (retval)
-               return retval;
-       return 0;
+       return u132_write_pcimem(u132, periodicstart,
+              ((9 * fi) / 10) & 0x3fff);
 }
 
 static char *hcfs2string(int state)
@@ -2701,28 +2698,18 @@ static int u132_roothub_setportfeature(struct u132 *u132, u16 wValue,
        if (wIndex == 0 || wIndex > u132->num_ports) {
                return -EINVAL;
        } else {
-               int retval;
                int port_index = wIndex - 1;
                struct u132_port *port = &u132->port[port_index];
                port->Status &= ~(1 << wValue);
                switch (wValue) {
                case USB_PORT_FEAT_SUSPEND:
-                       retval = u132_write_pcimem(u132,
-                               roothub.portstatus[port_index], RH_PS_PSS);
-                       if (retval)
-                               return retval;
-                       return 0;
+                       return u132_write_pcimem(u132,
+                              roothub.portstatus[port_index], RH_PS_PSS);
                case USB_PORT_FEAT_POWER:
-                       retval = u132_write_pcimem(u132,
-                               roothub.portstatus[port_index], RH_PS_PPS);
-                       if (retval)
-                               return retval;
-                       return 0;
+                       return u132_write_pcimem(u132,
+                              roothub.portstatus[port_index], RH_PS_PPS);
                case USB_PORT_FEAT_RESET:
-                       retval = u132_roothub_portreset(u132, port_index);
-                       if (retval)
-                               return retval;
-                       return 0;
+                       return u132_roothub_portreset(u132, port_index);
                default:
                        return -EPIPE;
                }
@@ -2737,7 +2724,6 @@ static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
        } else {
                int port_index = wIndex - 1;
                u32 temp;
-               int retval;
                struct u132_port *port = &u132->port[port_index];
                port->Status &= ~(1 << wValue);
                switch (wValue) {
@@ -2773,11 +2759,8 @@ static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
                default:
                        return -EPIPE;
                }
-               retval = u132_write_pcimem(u132, roothub.portstatus[port_index],
-                        temp);
-               if (retval)
-                       return retval;
-               return 0;
+               return u132_write_pcimem(u132, roothub.portstatus[port_index],
+                      temp);
        }
 }
 
index 745717ec9c89a0fa9297cdbdec749ecd79e12527..2d16faefb429b03a529304136c1eaf19deb15572 100644 (file)
@@ -99,6 +99,10 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
        xhci_dbg(xhci, "HCC PARAMS 0x%x:\n", (unsigned int) temp);
        xhci_dbg(xhci, "  HC generates %s bit addresses\n",
                        HCC_64BIT_ADDR(temp) ? "64" : "32");
+       xhci_dbg(xhci, "  HC %s Contiguous Frame ID Capability\n",
+                       HCC_CFC(temp) ? "has" : "hasn't");
+       xhci_dbg(xhci, "  HC %s generate Stopped - Short Package event\n",
+                       HCC_SPC(temp) ? "can" : "can't");
        /* FIXME */
        xhci_dbg(xhci, "  FIXME: more HCCPARAMS debugging\n");
 
index 32f4d564494a9f48cfebd328e61d3c281387d252..a47a1e89708678e6d55dd6a13e4fbed229bedfe2 100644 (file)
@@ -1812,7 +1812,9 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
        if (skip)
                goto td_cleanup;
 
-       if (trb_comp_code == COMP_STOP_INVAL || trb_comp_code == COMP_STOP) {
+       if (trb_comp_code == COMP_STOP_INVAL ||
+                       trb_comp_code == COMP_STOP ||
+                       trb_comp_code == COMP_STOP_SHORT) {
                /* The Endpoint Stop Command completion will take care of any
                 * stopped TDs.  A stopped TD may be restarted, so don't update
                 * the ring dequeue pointer or take this TD off any lists yet.
@@ -1919,8 +1921,22 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
                else
                        *status = 0;
                break;
-       case COMP_STOP_INVAL:
+       case COMP_STOP_SHORT:
+               if (event_trb == ep_ring->dequeue || event_trb == td->last_trb)
+                       xhci_warn(xhci, "WARN: Stopped Short Packet on ctrl setup or status TRB\n");
+               else
+                       td->urb->actual_length =
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+
+               return finish_td(xhci, td, event_trb, event, ep, status, false);
        case COMP_STOP:
+               /* Did we stop at data stage? */
+               if (event_trb != ep_ring->dequeue && event_trb != td->last_trb)
+                       td->urb->actual_length =
+                               td->urb->transfer_buffer_length -
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+               /* fall through */
+       case COMP_STOP_INVAL:
                return finish_td(xhci, td, event_trb, event, ep, status, false);
        default:
                if (!xhci_requires_manual_halt_cleanup(xhci,
@@ -2014,6 +2030,8 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
                }
                if ((xhci->quirks & XHCI_TRUST_TX_LENGTH))
                        trb_comp_code = COMP_SHORT_TX;
+       /* fallthrough */
+       case COMP_STOP_SHORT:
        case COMP_SHORT_TX:
                frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ?
                                -EREMOTEIO : 0;
@@ -2049,6 +2067,10 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
        if (trb_comp_code == COMP_SUCCESS || skip_td) {
                frame->actual_length = frame->length;
                td->urb->actual_length += frame->length;
+       } else if (trb_comp_code == COMP_STOP_SHORT) {
+               frame->actual_length =
+                       EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+               td->urb->actual_length += frame->actual_length;
        } else {
                for (cur_trb = ep_ring->dequeue,
                     cur_seg = ep_ring->deq_seg; cur_trb != event_trb;
@@ -2129,6 +2151,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                        *status = 0;
                }
                break;
+       case COMP_STOP_SHORT:
        case COMP_SHORT_TX:
                if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
                        *status = -EREMOTEIO;
@@ -2145,8 +2168,20 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                                td->urb->ep->desc.bEndpointAddress,
                                td->urb->transfer_buffer_length,
                                EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
+       /* Stopped - short packet completion */
+       if (trb_comp_code == COMP_STOP_SHORT) {
+               td->urb->actual_length =
+                       EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+
+               if (td->urb->transfer_buffer_length <
+                               td->urb->actual_length) {
+                       xhci_warn(xhci, "HC gave bad length of %d bytes txed\n",
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
+                       td->urb->actual_length = 0;
+                        /* status will be set by usb core for canceled urbs */
+               }
        /* Fast path - was this the last TRB in the TD for this URB? */
-       if (event_trb == td->last_trb) {
+       } else if (event_trb == td->last_trb) {
                if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
                        td->urb->actual_length =
                                td->urb->transfer_buffer_length -
@@ -2300,6 +2335,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
        case COMP_STOP_INVAL:
                xhci_dbg(xhci, "Stopped on No-op or Link TRB\n");
                break;
+       case COMP_STOP_SHORT:
+               xhci_dbg(xhci, "Stopped with short packet transfer detected\n");
+               break;
        case COMP_STALL:
                xhci_dbg(xhci, "Stalled endpoint\n");
                ep->ep_state |= EP_HALTED;
@@ -3041,9 +3079,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        struct xhci_td *td;
        struct scatterlist *sg;
        int num_sgs;
-       int trb_buff_len, this_sg_len, running_total;
+       int trb_buff_len, this_sg_len, running_total, ret;
        unsigned int total_packet_count;
+       bool zero_length_needed;
        bool first_trb;
+       int last_trb_num;
        u64 addr;
        bool more_trbs_coming;
 
@@ -3059,13 +3099,27 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
                        usb_endpoint_maxp(&urb->ep->desc));
 
-       trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
+       ret = prepare_transfer(xhci, xhci->devs[slot_id],
                        ep_index, urb->stream_id,
                        num_trbs, urb, 0, mem_flags);
-       if (trb_buff_len < 0)
-               return trb_buff_len;
+       if (ret < 0)
+               return ret;
 
        urb_priv = urb->hcpriv;
+
+       /* Deal with URB_ZERO_PACKET - need one more td/trb */
+       zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET &&
+               urb_priv->length == 2;
+       if (zero_length_needed) {
+               num_trbs++;
+               xhci_dbg(xhci, "Creating zero length td.\n");
+               ret = prepare_transfer(xhci, xhci->devs[slot_id],
+                               ep_index, urb->stream_id,
+                               1, urb, 1, mem_flags);
+               if (ret < 0)
+                       return ret;
+       }
+
        td = urb_priv->td[0];
 
        /*
@@ -3095,6 +3149,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                trb_buff_len = urb->transfer_buffer_length;
 
        first_trb = true;
+       last_trb_num = zero_length_needed ? 2 : 1;
        /* Queue the first TRB, even if it's zero-length */
        do {
                u32 field = 0;
@@ -3112,12 +3167,15 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                /* Chain all the TRBs together; clear the chain bit in the last
                 * TRB to indicate it's the last TRB in the chain.
                 */
-               if (num_trbs > 1) {
+               if (num_trbs > last_trb_num) {
                        field |= TRB_CHAIN;
-               } else {
-                       /* FIXME - add check for ZERO_PACKET flag before this */
+               } else if (num_trbs == last_trb_num) {
                        td->last_trb = ep_ring->enqueue;
                        field |= TRB_IOC;
+               } else if (zero_length_needed && num_trbs == 1) {
+                       trb_buff_len = 0;
+                       urb_priv->td[1]->last_trb = ep_ring->enqueue;
+                       field |= TRB_IOC;
                }
 
                /* Only set interrupt on short packet for IN endpoints */
@@ -3179,7 +3237,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                if (running_total + trb_buff_len > urb->transfer_buffer_length)
                        trb_buff_len =
                                urb->transfer_buffer_length - running_total;
-       } while (running_total < urb->transfer_buffer_length);
+       } while (num_trbs > 0);
 
        check_trb_math(urb, num_trbs, running_total);
        giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
@@ -3197,7 +3255,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        int num_trbs;
        struct xhci_generic_trb *start_trb;
        bool first_trb;
+       int last_trb_num;
        bool more_trbs_coming;
+       bool zero_length_needed;
        int start_cycle;
        u32 field, length_field;
 
@@ -3228,7 +3288,6 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                num_trbs++;
                running_total += TRB_MAX_BUFF_SIZE;
        }
-       /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
 
        ret = prepare_transfer(xhci, xhci->devs[slot_id],
                        ep_index, urb->stream_id,
@@ -3237,6 +3296,20 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                return ret;
 
        urb_priv = urb->hcpriv;
+
+       /* Deal with URB_ZERO_PACKET - need one more td/trb */
+       zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET &&
+               urb_priv->length == 2;
+       if (zero_length_needed) {
+               num_trbs++;
+               xhci_dbg(xhci, "Creating zero length td.\n");
+               ret = prepare_transfer(xhci, xhci->devs[slot_id],
+                               ep_index, urb->stream_id,
+                               1, urb, 1, mem_flags);
+               if (ret < 0)
+                       return ret;
+       }
+
        td = urb_priv->td[0];
 
        /*
@@ -3258,7 +3331,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                trb_buff_len = urb->transfer_buffer_length;
 
        first_trb = true;
-
+       last_trb_num = zero_length_needed ? 2 : 1;
        /* Queue the first TRB, even if it's zero-length */
        do {
                u32 remainder = 0;
@@ -3275,12 +3348,15 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                /* Chain all the TRBs together; clear the chain bit in the last
                 * TRB to indicate it's the last TRB in the chain.
                 */
-               if (num_trbs > 1) {
+               if (num_trbs > last_trb_num) {
                        field |= TRB_CHAIN;
-               } else {
-                       /* FIXME - add check for ZERO_PACKET flag before this */
+               } else if (num_trbs == last_trb_num) {
                        td->last_trb = ep_ring->enqueue;
                        field |= TRB_IOC;
+               } else if (zero_length_needed && num_trbs == 1) {
+                       trb_buff_len = 0;
+                       urb_priv->td[1]->last_trb = ep_ring->enqueue;
+                       field |= TRB_IOC;
                }
 
                /* Only set interrupt on short packet for IN endpoints */
@@ -3318,7 +3394,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                trb_buff_len = urb->transfer_buffer_length - running_total;
                if (trb_buff_len > TRB_MAX_BUFF_SIZE)
                        trb_buff_len = TRB_MAX_BUFF_SIZE;
-       } while (running_total < urb->transfer_buffer_length);
+       } while (num_trbs > 0);
 
        check_trb_math(urb, num_trbs, running_total);
        giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
@@ -3517,6 +3593,97 @@ static unsigned int xhci_get_last_burst_packet_count(struct xhci_hcd *xhci,
        }
 }
 
+/*
+ * Calculates Frame ID field of the isochronous TRB identifies the
+ * target frame that the Interval associated with this Isochronous
+ * Transfer Descriptor will start on. Refer to 4.11.2.5 in 1.1 spec.
+ *
+ * Returns actual frame id on success, negative value on error.
+ */
+static int xhci_get_isoc_frame_id(struct xhci_hcd *xhci,
+               struct urb *urb, int index)
+{
+       int start_frame, ist, ret = 0;
+       int start_frame_id, end_frame_id, current_frame_id;
+
+       if (urb->dev->speed == USB_SPEED_LOW ||
+                       urb->dev->speed == USB_SPEED_FULL)
+               start_frame = urb->start_frame + index * urb->interval;
+       else
+               start_frame = (urb->start_frame + index * urb->interval) >> 3;
+
+       /* Isochronous Scheduling Threshold (IST, bits 0~3 in HCSPARAMS2):
+        *
+        * If bit [3] of IST is cleared to '0', software can add a TRB no
+        * later than IST[2:0] Microframes before that TRB is scheduled to
+        * be executed.
+        * If bit [3] of IST is set to '1', software can add a TRB no later
+        * than IST[2:0] Frames before that TRB is scheduled to be executed.
+        */
+       ist = HCS_IST(xhci->hcs_params2) & 0x7;
+       if (HCS_IST(xhci->hcs_params2) & (1 << 3))
+               ist <<= 3;
+
+       /* Software shall not schedule an Isoch TD with a Frame ID value that
+        * is less than the Start Frame ID or greater than the End Frame ID,
+        * where:
+        *
+        * End Frame ID = (Current MFINDEX register value + 895 ms.) MOD 2048
+        * Start Frame ID = (Current MFINDEX register value + IST + 1) MOD 2048
+        *
+        * Both the End Frame ID and Start Frame ID values are calculated
+        * in microframes. When software determines the valid Frame ID value;
+        * The End Frame ID value should be rounded down to the nearest Frame
+        * boundary, and the Start Frame ID value should be rounded up to the
+        * nearest Frame boundary.
+        */
+       current_frame_id = readl(&xhci->run_regs->microframe_index);
+       start_frame_id = roundup(current_frame_id + ist + 1, 8);
+       end_frame_id = rounddown(current_frame_id + 895 * 8, 8);
+
+       start_frame &= 0x7ff;
+       start_frame_id = (start_frame_id >> 3) & 0x7ff;
+       end_frame_id = (end_frame_id >> 3) & 0x7ff;
+
+       xhci_dbg(xhci, "%s: index %d, reg 0x%x start_frame_id 0x%x, end_frame_id 0x%x, start_frame 0x%x\n",
+                __func__, index, readl(&xhci->run_regs->microframe_index),
+                start_frame_id, end_frame_id, start_frame);
+
+       if (start_frame_id < end_frame_id) {
+               if (start_frame > end_frame_id ||
+                               start_frame < start_frame_id)
+                       ret = -EINVAL;
+       } else if (start_frame_id > end_frame_id) {
+               if ((start_frame > end_frame_id &&
+                               start_frame < start_frame_id))
+                       ret = -EINVAL;
+       } else {
+                       ret = -EINVAL;
+       }
+
+       if (index == 0) {
+               if (ret == -EINVAL || start_frame == start_frame_id) {
+                       start_frame = start_frame_id + 1;
+                       if (urb->dev->speed == USB_SPEED_LOW ||
+                                       urb->dev->speed == USB_SPEED_FULL)
+                               urb->start_frame = start_frame;
+                       else
+                               urb->start_frame = start_frame << 3;
+                       ret = 0;
+               }
+       }
+
+       if (ret) {
+               xhci_warn(xhci, "Frame ID %d (reg %d, index %d) beyond range (%d, %d)\n",
+                               start_frame, current_frame_id, index,
+                               start_frame_id, end_frame_id);
+               xhci_warn(xhci, "Ignore frame ID field, use SIA bit instead\n");
+               return ret;
+       }
+
+       return start_frame;
+}
+
 /* This is for isoc transfer */
 static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                struct urb *urb, int slot_id, unsigned int ep_index)
@@ -3533,7 +3700,9 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        u64 start_addr, addr;
        int i, j;
        bool more_trbs_coming;
+       struct xhci_virt_ep *xep;
 
+       xep = &xhci->devs[slot_id]->eps[ep_index];
        ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
 
        num_tds = urb->number_of_packets;
@@ -3581,6 +3750,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
                td = urb_priv->td[i];
                for (j = 0; j < trbs_per_td; j++) {
+                       int frame_id = 0;
                        u32 remainder = 0;
                        field = 0;
 
@@ -3589,8 +3759,20 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                                        TRB_TLBPC(residue);
                                /* Queue the isoc TRB */
                                field |= TRB_TYPE(TRB_ISOC);
-                               /* Assume URB_ISO_ASAP is set */
-                               field |= TRB_SIA;
+
+                               /* Calculate Frame ID and SIA fields */
+                               if (!(urb->transfer_flags & URB_ISO_ASAP) &&
+                                               HCC_CFC(xhci->hcc_params)) {
+                                       frame_id = xhci_get_isoc_frame_id(xhci,
+                                                                         urb,
+                                                                         i);
+                                       if (frame_id >= 0)
+                                               field |= TRB_FRAME_ID(frame_id);
+                                       else
+                                               field |= TRB_SIA;
+                               } else
+                                       field |= TRB_SIA;
+
                                if (i == 0) {
                                        if (start_cycle == 0)
                                                field |= 0x1;
@@ -3666,6 +3848,10 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                }
        }
 
+       /* store the next frame id */
+       if (HCC_CFC(xhci->hcc_params))
+               xep->next_frame_id = urb->start_frame + num_tds * urb->interval;
+
        if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) {
                if (xhci->quirks & XHCI_AMD_PLL_FIX)
                        usb_amd_quirk_pll_disable();
@@ -3699,12 +3885,34 @@ cleanup:
        return ret;
 }
 
+static int ep_ring_is_processing(struct xhci_hcd *xhci,
+               int slot_id, unsigned int ep_index)
+{
+       struct xhci_virt_device *xdev;
+       struct xhci_ring *ep_ring;
+       struct xhci_ep_ctx *ep_ctx;
+       struct xhci_virt_ep *xep;
+       dma_addr_t hw_deq;
+
+       xdev = xhci->devs[slot_id];
+       xep = &xhci->devs[slot_id]->eps[ep_index];
+       ep_ring = xep->ring;
+       ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
+
+       if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) != EP_STATE_RUNNING)
+               return 0;
+
+       hw_deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK;
+       return (hw_deq !=
+               xhci_trb_virt_to_dma(ep_ring->enq_seg, ep_ring->enqueue));
+}
+
 /*
  * Check transfer ring to guarantee there is enough room for the urb.
  * Update ISO URB start_frame and interval.
- * Update interval as xhci_queue_intr_tx does. Just use xhci frame_index to
- * update the urb->start_frame by now.
- * Always assume URB_ISO_ASAP set, and NEVER use urb->start_frame as input.
+ * Update interval as xhci_queue_intr_tx does. Use xhci frame_index to
+ * update urb->start_frame if URB_ISO_ASAP is set in transfer_flags or
+ * Contiguous Frame ID is not supported by HC.
  */
 int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
                struct urb *urb, int slot_id, unsigned int ep_index)
@@ -3717,8 +3925,11 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
        int ep_interval;
        int num_tds, num_trbs, i;
        int ret;
+       struct xhci_virt_ep *xep;
+       int ist;
 
        xdev = xhci->devs[slot_id];
+       xep = &xhci->devs[slot_id]->eps[ep_index];
        ep_ring = xdev->eps[ep_index].ring;
        ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
 
@@ -3735,14 +3946,10 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
        if (ret)
                return ret;
 
-       start_frame = readl(&xhci->run_regs->microframe_index);
-       start_frame &= 0x3fff;
-
-       urb->start_frame = start_frame;
-       if (urb->dev->speed == USB_SPEED_LOW ||
-                       urb->dev->speed == USB_SPEED_FULL)
-               urb->start_frame >>= 3;
-
+       /*
+        * Check interval value. This should be done before we start to
+        * calculate the start frame value.
+        */
        xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx->ep_info));
        ep_interval = urb->interval;
        /* Convert to microframes */
@@ -3763,6 +3970,40 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
                                urb->dev->speed == USB_SPEED_FULL)
                        urb->interval /= 8;
        }
+
+       /* Calculate the start frame and put it in urb->start_frame. */
+       if (HCC_CFC(xhci->hcc_params) &&
+                       ep_ring_is_processing(xhci, slot_id, ep_index)) {
+               urb->start_frame = xep->next_frame_id;
+               goto skip_start_over;
+       }
+
+       start_frame = readl(&xhci->run_regs->microframe_index);
+       start_frame &= 0x3fff;
+       /*
+        * Round up to the next frame and consider the time before trb really
+        * gets scheduled by hardare.
+        */
+       ist = HCS_IST(xhci->hcs_params2) & 0x7;
+       if (HCS_IST(xhci->hcs_params2) & (1 << 3))
+               ist <<= 3;
+       start_frame += ist + XHCI_CFC_DELAY;
+       start_frame = roundup(start_frame, 8);
+
+       /*
+        * Round up to the next ESIT (Endpoint Service Interval Time) if ESIT
+        * is greate than 8 microframes.
+        */
+       if (urb->dev->speed == USB_SPEED_LOW ||
+                       urb->dev->speed == USB_SPEED_FULL) {
+               start_frame = roundup(start_frame, urb->interval << 3);
+               urb->start_frame = start_frame >> 3;
+       } else {
+               start_frame = roundup(start_frame, urb->interval);
+               urb->start_frame = start_frame;
+       }
+
+skip_start_over:
        ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free;
 
        return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index);
index 526ebc0c7e720b9d766bcf6abf1bc65672e584bb..6b0f4a47e4021d83e01fb76a0a1aa18d6b3ca793 100644 (file)
@@ -1340,6 +1340,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
 
        if (usb_endpoint_xfer_isoc(&urb->ep->desc))
                size = urb->number_of_packets;
+       else if (usb_endpoint_is_bulk_out(&urb->ep->desc) &&
+           urb->transfer_buffer_length > 0 &&
+           urb->transfer_flags & URB_ZERO_PACKET &&
+           !(urb->transfer_buffer_length % usb_endpoint_maxp(&urb->ep->desc)))
+               size = 2;
        else
                size = 1;
 
@@ -3117,7 +3122,7 @@ static u32 xhci_calculate_no_streams_bitmask(struct xhci_hcd *xhci,
 }
 
 /*
- * The USB device drivers use this function (though the HCD interface in USB
+ * The USB device drivers use this function (through the HCD interface in USB
  * core) to prepare a set of bulk endpoints to use streams.  Streams are used to
  * coordinate mass storage command queueing across multiple endpoints (basically
  * a stream ID == a task ID).
@@ -4678,7 +4683,6 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
 {
        struct xhci_hcd *xhci;
        u16 mel;
-       int ret;
 
        xhci = hcd_to_xhci(hcd);
        if (!xhci || !(xhci->quirks & XHCI_LPM_SUPPORT) ||
@@ -4686,10 +4690,7 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
                return 0;
 
        mel = calculate_max_exit_latency(udev, state, USB3_LPM_DISABLED);
-       ret = xhci_change_max_exit_latency(xhci, udev, mel);
-       if (ret)
-               return ret;
-       return 0;
+       return xhci_change_max_exit_latency(xhci, udev, mel);
 }
 #else /* CONFIG_PM */
 
index ed2ebf647c380ebbdfe647544fb137283219cf87..dbda41e91c843f2e289c4a4aa0d4129f2641f2a9 100644 (file)
@@ -119,6 +119,10 @@ struct xhci_cap_regs {
 #define HCC_LTC(p)             ((p) & (1 << 6))
 /* true: no secondary Stream ID Support */
 #define HCC_NSS(p)             ((p) & (1 << 7))
+/* true: HC supports Stopped - Short Packet */
+#define HCC_SPC(p)             ((p) & (1 << 9))
+/* true: HC has Contiguous Frame ID Capability */
+#define HCC_CFC(p)             ((p) & (1 << 11))
 /* Max size for Primary Stream Arrays - 2^(n+1), where n is bits 12:15 */
 #define HCC_MAX_PSA(p)         (1 << ((((p) >> 12) & 0xf) + 1))
 /* Extended Capabilities pointer from PCI base - section 5.3.6 */
@@ -891,6 +895,8 @@ struct xhci_virt_ep {
        /* Bandwidth checking storage */
        struct xhci_bw_info     bw_info;
        struct list_head        bw_endpoint_list;
+       /* Isoch Frame ID checking storage */
+       int                     next_frame_id;
 };
 
 enum xhci_overhead_type {
@@ -1059,8 +1065,8 @@ struct xhci_transfer_event {
 #define COMP_STOP      26
 /* Same as COMP_EP_STOPPED, but the transferred length in the event is invalid */
 #define COMP_STOP_INVAL        27
-/* Control Abort Error - Debug Capability - control pipe aborted */
-#define COMP_DBG_ABORT 28
+/* Same as COMP_EP_STOPPED, but a short packet detected */
+#define COMP_STOP_SHORT        28
 /* Max Exit Latency Too Large Error */
 #define COMP_MEL_ERR   29
 /* TRB type 30 reserved */
@@ -1165,6 +1171,7 @@ enum xhci_setup_dev {
 
 /* Isochronous TRB specific fields */
 #define TRB_SIA                        (1<<31)
+#define TRB_FRAME_ID(p)                (((p) & 0x7ff) << 20)
 
 struct xhci_generic_trb {
        __le32 field[4];
@@ -1601,6 +1608,8 @@ struct xhci_driver_overrides {
        int (*start)(struct usb_hcd *hcd);
 };
 
+#define        XHCI_CFC_DELAY          10
+
 /* convert between an HCD pointer and the corresponding EHCI_HCD */
 static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd)
 {
index 8ab1f8f3c26e6a2b7b3630b39356968ac98bf38d..52c27cab78c3e44d1927c7bcacebc7fbcf1f7c61 100644 (file)
@@ -2568,11 +2568,7 @@ static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn)
                                            0x00);
        if (UxxxStatus)
                return UxxxStatus;
-       UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
-                                          &pcidata);
-       if (UxxxStatus)
-               return UxxxStatus;
-       return 0;
+       return ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, &pcidata);
 }
 
 static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk)
@@ -2695,11 +2691,7 @@ static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi)
                }
        }
        if (ftdi->function > 0) {
-               UxxxStatus = ftdi_elan_setup_controller(ftdi,
-                                                       ftdi->function - 1);
-               if (UxxxStatus)
-                       return UxxxStatus;
-               return 0;
+               return ftdi_elan_setup_controller(ftdi, ftdi->function - 1);
        } else if (controllers > 0) {
                return -ENXIO;
        } else if (unrecognized > 0) {
index 1334a3de31b8e937756d9546073d41f71ee513bd..a0cfead6150f13a58fc83d50fa0a0559b8bc8908 100644 (file)
@@ -482,11 +482,7 @@ static int dsps_musb_init(struct musb *musb)
                dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val);
        }
 
-       ret = dsps_musb_dbg_init(musb, glue);
-       if (ret)
-               return ret;
-
-       return 0;
+       return dsps_musb_dbg_init(musb, glue);
 }
 
 static int dsps_musb_exit(struct musb *musb)
index e0556f7832b5534c29d593b165f473995e96e1da..01d4e4cdbc79ef3125482ccd0e94e8372315798e 100644 (file)
@@ -96,11 +96,7 @@ static int keystone_usbphy_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, k_phy);
 
-       ret = usb_add_phy_dev(&k_phy->usb_phy_gen.phy);
-       if (ret)
-               return ret;
-
-       return 0;
+       return usb_add_phy_dev(&k_phy->usb_phy_gen.phy);
 }
 
 static int keystone_usbphy_remove(struct platform_device *pdev)
index 3fcc0483a0811e8f7e2984aea1c4a11ce2da0951..4d863ebc117c0f59cce46f39fda4d191e93b9843 100644 (file)
@@ -506,11 +506,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
 
        device_set_wakeup_capable(&pdev->dev, true);
 
-       ret = usb_add_phy_dev(&mxs_phy->phy);
-       if (ret)
-               return ret;
-
-       return 0;
+       return usb_add_phy_dev(&mxs_phy->phy);
 }
 
 static int mxs_phy_remove(struct platform_device *pdev)
index dc2aa326120252bcb1ed3eb45c3f31459d4f6497..54f916fa238d0428bed717b9f86121864ceb8d72 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
 #include "common.h"
 
 /*
@@ -50,6 +51,8 @@ struct usbhsg_gpriv {
        int                      uep_size;
 
        struct usb_gadget_driver        *driver;
+       struct usb_phy          *transceiver;
+       bool                     vbus_active;
 
        u32     status;
 #define USBHSG_STATUS_STARTED          (1 << 0)
@@ -872,6 +875,27 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
        return 0;
 }
 
+/*
+ * VBUS provided by the PHY
+ */
+static int usbhsm_phy_get_vbus(struct platform_device *pdev)
+{
+       struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
+       struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
+
+       return  gpriv->vbus_active;
+}
+
+static void usbhs_mod_phy_mode(struct usbhs_priv *priv)
+{
+       struct usbhs_mod_info *info = &priv->mod_info;
+
+       info->irq_vbus          = NULL;
+       priv->pfunc.get_vbus    = usbhsm_phy_get_vbus;
+
+       usbhs_irq_callback_update(priv, NULL);
+}
+
 /*
  *
  *             linux usb function
@@ -882,12 +906,28 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget,
 {
        struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
        struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
+       struct device *dev = usbhs_priv_to_dev(priv);
+       int ret;
 
        if (!driver             ||
            !driver->setup      ||
            driver->max_speed < USB_SPEED_FULL)
                return -EINVAL;
 
+       /* connect to bus through transceiver */
+       if (!IS_ERR_OR_NULL(gpriv->transceiver)) {
+               ret = otg_set_peripheral(gpriv->transceiver->otg,
+                                       &gpriv->gadget);
+               if (ret) {
+                       dev_err(dev, "%s: can't bind to transceiver\n",
+                               gpriv->gadget.name);
+                       return ret;
+               }
+
+               /* get vbus using phy versions */
+               usbhs_mod_phy_mode(priv);
+       }
+
        /* first hook up the driver ... */
        gpriv->driver = driver;
 
@@ -900,6 +940,10 @@ static int usbhsg_gadget_stop(struct usb_gadget *gadget)
        struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
        usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD);
+
+       if (!IS_ERR_OR_NULL(gpriv->transceiver))
+               otg_set_peripheral(gpriv->transceiver->otg, NULL);
+
        gpriv->driver = NULL;
 
        return 0;
@@ -947,12 +991,26 @@ static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self)
        return 0;
 }
 
+static int usbhsg_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+       struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
+       struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
+       struct platform_device *pdev = usbhs_priv_to_pdev(priv);
+
+       gpriv->vbus_active = !!is_active;
+
+       renesas_usbhs_call_notify_hotplug(pdev);
+
+       return 0;
+}
+
 static const struct usb_gadget_ops usbhsg_gadget_ops = {
        .get_frame              = usbhsg_get_frame,
        .set_selfpowered        = usbhsg_set_selfpowered,
        .udc_start              = usbhsg_gadget_start,
        .udc_stop               = usbhsg_gadget_stop,
        .pullup                 = usbhsg_pullup,
+       .vbus_session           = usbhsg_vbus_session,
 };
 
 static int usbhsg_start(struct usbhs_priv *priv)
@@ -994,6 +1052,10 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
                goto usbhs_mod_gadget_probe_err_gpriv;
        }
 
+       gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
+       dev_info(dev, "%stransceiver found\n",
+                gpriv->transceiver ? "" : "no ");
+
        /*
         * CAUTION
         *
index 460a40669967855cfeea7c6cc911064822c6882a..31a8b47f1ac65f325ce285aa80bce66bf74298d7 100644 (file)
@@ -1137,13 +1137,9 @@ static int mxuport_port_probe(struct usb_serial_port *port)
                return err;
 
        /* Set interface (RS-232) */
-       err = mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
-                                   MX_INT_RS232,
-                                   port->port_number);
-       if (err)
-               return err;
-
-       return 0;
+       return mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
+                                    MX_INT_RS232,
+                                    port->port_number);
 }
 
 static int mxuport_alloc_write_urb(struct usb_serial *serial,
index 540add24a12ffa428bda0e7a0db07650ecd29eab..5e67f63b2e462ffc68b5acc1a9f8557828e44489 100644 (file)
@@ -1111,7 +1111,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
         * command phase and the data phase.  Some devices need a little
         * more than that, probably because of clock rate inaccuracies. */
        if (unlikely(us->fflags & US_FL_GO_SLOW))
-               udelay(125);
+               usleep_range(125, 150);
 
        if (transfer_length) {
                unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? 
index 2a2f56b292c172408f889a33c63297d6e7d661aa..cebdbbb4aa6901870fd0706b4434f4f676f3176c 100644 (file)
 #define FSL_UTMI_PHY_DLY       10      /*As per P1010RM, delay for UTMI
                                PHY CLK to become stable - 10ms*/
 #define FSL_USB_PHY_CLK_TIMEOUT        10000   /* uSec */
-#define FSL_USB_VER_OLD                0
-#define FSL_USB_VER_1_6                1
-#define FSL_USB_VER_2_2                2
-#define FSL_USB_VER_2_4                3
-#define FSL_USB_VER_2_5                4
 
 #include <linux/types.h>
 
  *
  */
 
+enum fsl_usb2_controller_ver {
+       FSL_USB_VER_NONE = -1,
+       FSL_USB_VER_OLD = 0,
+       FSL_USB_VER_1_6 = 1,
+       FSL_USB_VER_2_2 = 2,
+       FSL_USB_VER_2_4 = 3,
+       FSL_USB_VER_2_5 = 4,
+};
+
 enum fsl_usb2_operating_modes {
        FSL_USB2_MPH_HOST,
        FSL_USB2_DR_HOST,
@@ -65,6 +69,7 @@ enum fsl_usb2_phy_modes {
        FSL_USB2_PHY_UTMI,
        FSL_USB2_PHY_UTMI_WIDE,
        FSL_USB2_PHY_SERIAL,
+       FSL_USB2_PHY_UTMI_DUAL,
 };
 
 struct clk;
@@ -72,7 +77,7 @@ struct platform_device;
 
 struct fsl_usb2_platform_data {
        /* board specific information */
-       int                             controller_ver;
+       enum fsl_usb2_controller_ver    controller_ver;
        enum fsl_usb2_operating_modes   operating_mode;
        enum fsl_usb2_phy_modes         phy_mode;
        unsigned int                    port_enables;
@@ -93,6 +98,8 @@ struct fsl_usb2_platform_data {
 
        unsigned        suspended:1;
        unsigned        already_suspended:1;
+       unsigned        has_fsl_erratum_a007792:1;
+       unsigned        check_phy_clk_valid:1;
 
        /* register save area for suspend/resume */
        u32             pm_command;
index c9aa7792de10ac1b7f4676d4a0a5c8b6ac5c362f..d2784c10bfe2ce23dfcd64d773dbe3beaeb34c22 100644 (file)
@@ -564,9 +564,9 @@ extern void usb_ep0_reinit(struct usb_device *);
 
 /*-------------------------------------------------------------------------*/
 
-/* class requests from USB 3.0 hub spec, table 10-5 */
-#define SetHubDepth            (0x3000 | HUB_SET_DEPTH)
-#define GetPortErrorCount      (0x8000 | HUB_GET_PORT_ERR_COUNT)
+/* class requests from USB 3.1 hub spec, table 10-7 */
+#define SetHubDepth            (0x2000 | HUB_SET_DEPTH)
+#define GetPortErrorCount      (0xa300 | HUB_GET_PORT_ERR_COUNT)
 
 /*
  * Generic bandwidth allocation constants/support