xhci: Fix front USB ports on ASUS PRIME B350M-A
[pandora-kernel.git] / drivers / usb / host / xhci.c
index cbf100c..550f4e7 100644 (file)
@@ -33,6 +33,8 @@
 #define DRIVER_AUTHOR "Sarah Sharp"
 #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
 
+#define        PORT_WAKE_BITS  (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)
+
 /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
 static int link_quirk;
 module_param(link_quirk, int, S_IRUGO | S_IWUSR);
@@ -139,7 +141,8 @@ static int xhci_start(struct xhci_hcd *xhci)
                                "waited %u microseconds.\n",
                                XHCI_MAX_HALT_USEC);
        if (!ret)
-               xhci->xhc_state &= ~XHCI_STATE_HALTED;
+               xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING);
+
        return ret;
 }
 
@@ -167,6 +170,16 @@ int xhci_reset(struct xhci_hcd *xhci)
        command |= CMD_RESET;
        xhci_writel(xhci, command, &xhci->op_regs->command);
 
+       /* Existing Intel xHCI controllers require a delay of 1 mS,
+        * after setting the CMD_RESET bit, and before accessing any
+        * HC registers. This allows the HC to complete the
+        * reset operation and be ready for HC register access.
+        * Without this delay, the subsequent HC register access,
+        * may result in a system hang very rarely.
+        */
+       if (xhci->quirks & XHCI_INTEL_HOST)
+               udelay(1000);
+
        ret = handshake(xhci, &xhci->op_regs->command,
                        CMD_RESET, 0, 10 * 1000 * 1000);
        if (ret)
@@ -867,24 +880,65 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
        xhci_set_cmd_ring_deq(xhci);
 }
 
+static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
+{
+       int port_index;
+       __le32 __iomem **port_array;
+       unsigned long flags;
+       u32 t1, t2;
+
+       spin_lock_irqsave(&xhci->lock, flags);
+
+       /* disble usb3 ports Wake bits*/
+       port_index = xhci->num_usb3_ports;
+       port_array = xhci->usb3_ports;
+       while (port_index--) {
+               t1 = readl(port_array[port_index]);
+               t1 = xhci_port_state_to_neutral(t1);
+               t2 = t1 & ~PORT_WAKE_BITS;
+               if (t1 != t2)
+                       writel(t2, port_array[port_index]);
+       }
+
+       /* disble usb2 ports Wake bits*/
+       port_index = xhci->num_usb2_ports;
+       port_array = xhci->usb2_ports;
+       while (port_index--) {
+               t1 = readl(port_array[port_index]);
+               t1 = xhci_port_state_to_neutral(t1);
+               t2 = t1 & ~PORT_WAKE_BITS;
+               if (t1 != t2)
+                       writel(t2, port_array[port_index]);
+       }
+
+       spin_unlock_irqrestore(&xhci->lock, flags);
+}
+
 /*
  * Stop HC (not bus-specific)
  *
  * This is called when the machine transition into S3/S4 mode.
  *
  */
-int xhci_suspend(struct xhci_hcd *xhci)
+int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
 {
        int                     rc = 0;
        unsigned int            delay = XHCI_MAX_HALT_USEC;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        u32                     command;
 
+       /* Clear root port wake on bits if wakeup not allowed. */
+       if (!do_wakeup)
+               xhci_disable_port_wake_on_bits(xhci);
+
        /* Don't poll the roothubs on bus suspend. */
        xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
        clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
        del_timer_sync(&hcd->rh_timer);
 
+       if (xhci->quirks & XHCI_SUSPEND_DELAY)
+               usleep_range(1000, 1500);
+
        spin_lock_irq(&xhci->lock);
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
@@ -1471,59 +1525,47 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
        unsigned int ep_index;
        struct xhci_ring *ep_ring;
        struct xhci_virt_ep *ep;
+       struct xhci_virt_device *vdev;
 
        xhci = hcd_to_xhci(hcd);
        spin_lock_irqsave(&xhci->lock, flags);
        /* Make sure the URB hasn't completed or been unlinked already */
        ret = usb_hcd_check_unlink_urb(hcd, urb, status);
-       if (ret || !urb->hcpriv)
+       if (ret)
                goto done;
-       temp = xhci_readl(xhci, &xhci->op_regs->status);
-       if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
-               xhci_dbg(xhci, "HW died, freeing TD.\n");
-               urb_priv = urb->hcpriv;
-               for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
-                       td = urb_priv->td[i];
-                       if (!list_empty(&td->td_list))
-                               list_del_init(&td->td_list);
-                       if (!list_empty(&td->cancelled_td_list))
-                               list_del_init(&td->cancelled_td_list);
-               }
 
-               usb_hcd_unlink_urb_from_ep(hcd, urb);
-               spin_unlock_irqrestore(&xhci->lock, flags);
-               usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
-               xhci_urb_free_priv(xhci, urb_priv);
-               return ret;
-       }
-       if ((xhci->xhc_state & XHCI_STATE_DYING) ||
-                       (xhci->xhc_state & XHCI_STATE_HALTED)) {
-               xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
-                               "non-responsive xHCI host.\n",
-                               urb->ep->desc.bEndpointAddress, urb);
-               /* Let the stop endpoint command watchdog timer (which set this
-                * state) finish cleaning up the endpoint TD lists.  We must
-                * have caught it in the middle of dropping a lock and giving
-                * back an URB.
-                */
-               goto done;
-       }
+       /* give back URB now if we can't queue it for cancel */
+       vdev = xhci->devs[urb->dev->slot_id];
+       urb_priv = urb->hcpriv;
+       if (!vdev || !urb_priv)
+               goto err_giveback;
 
        xhci_dbg(xhci, "Cancel URB %p\n", urb);
        xhci_dbg(xhci, "Event ring:\n");
        xhci_debug_ring(xhci, xhci->event_ring);
        ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-       ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
+       ep = &vdev->eps[ep_index];
        ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
-       if (!ep_ring) {
-               ret = -EINVAL;
-               goto done;
-       }
+       if (!ep || !ep_ring)
+               goto err_giveback;
 
        xhci_dbg(xhci, "Endpoint ring:\n");
        xhci_debug_ring(xhci, ep_ring);
 
-       urb_priv = urb->hcpriv;
+       temp = xhci_readl(xhci, &xhci->op_regs->status);
+       if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
+               xhci_dbg(xhci, "HW died, freeing TD.\n");
+               for (i = urb_priv->td_cnt;
+                    i < urb_priv->length;
+                    i++) {
+                       td = urb_priv->td[i];
+                       if (!list_empty(&td->td_list))
+                               list_del_init(&td->td_list);
+                       if (!list_empty(&td->cancelled_td_list))
+                               list_del_init(&td->cancelled_td_list);
+               }
+               goto err_giveback;
+       }
 
        for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
                td = urb_priv->td[i];
@@ -1545,6 +1587,14 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 done:
        spin_unlock_irqrestore(&xhci->lock, flags);
        return ret;
+
+err_giveback:
+       if (urb_priv)
+               xhci_urb_free_priv(xhci, urb_priv);
+       usb_hcd_unlink_urb_from_ep(hcd, urb);
+       spin_unlock_irqrestore(&xhci->lock, flags);
+       usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
+       return ret;
 }
 
 /* Drop an endpoint from a new bandwidth configuration for this device.
@@ -3321,6 +3371,9 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
                        return -EINVAL;
        }
 
+       if (virt_dev->tt_info)
+               old_active_eps = virt_dev->tt_info->active_eps;
+
        if (virt_dev->udev != udev) {
                /* If the virt_dev and the udev does not match, this virt_dev
                 * may belong to another udev.
@@ -4076,8 +4129,16 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
        ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
        slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
        slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
+       /*
+        * refer to section 6.2.2: MTT should be 0 for full speed hub,
+        * but it may be already set to 1 when setup an xHCI virtual
+        * device, so clear it anyway.
+        */
        if (tt->multi)
                slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+       else if (hdev->speed == USB_SPEED_FULL)
+               slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
+
        if (xhci->hci_version > 0x95) {
                xhci_dbg(xhci, "xHCI version %x needs hub "
                                "TT think time and number of ports\n",
@@ -4238,6 +4299,9 @@ static int __init xhci_hcd_init(void)
 {
        int retval;
 
+       if (usb_disabled())
+               return -ENODEV;
+
        retval = xhci_register_pci();
        if (retval < 0) {
                printk(KERN_DEBUG "Problem registering PCI driver.");