LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
 
        xhci_zero_in_ctx(xhci, virt_dev);
-       /* Free any old rings */
+       /* Install new rings and free or cache any old rings */
        for (i = 1; i < 31; ++i) {
-               if (virt_dev->eps[i].new_ring) {
-                       xhci_ring_free(xhci, virt_dev->eps[i].ring);
-                       virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
-                       virt_dev->eps[i].new_ring = NULL;
+               int rings_cached;
+
+               if (!virt_dev->eps[i].new_ring)
+                       continue;
+               /* Only cache or free the old ring if it exists.
+                * It may not if this is the first add of an endpoint.
+                */
+               if (virt_dev->eps[i].ring) {
+                       rings_cached = virt_dev->num_rings_cached;
+                       if (rings_cached < XHCI_MAX_RINGS_CACHED) {
+                               virt_dev->num_rings_cached++;
+                               rings_cached = virt_dev->num_rings_cached;
+                               virt_dev->ring_cache[rings_cached] =
+                                       virt_dev->eps[i].ring;
+                               xhci_dbg(xhci, "Cached old ring, "
+                                               "%d ring%s cached\n",
+                                               rings_cached,
+                                               (rings_cached > 1) ? "s" : "");
+                       } else {
+                               xhci_ring_free(xhci, virt_dev->eps[i].ring);
+                               xhci_dbg(xhci, "Ring cache full (%d rings), "
+                                               "freeing ring\n",
+                                               virt_dev->num_rings_cached);
+                       }
                }
+               virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
+               virt_dev->eps[i].new_ring = NULL;
        }
 
        return ret;
 
        kfree(ring);
 }
 
+static void xhci_initialize_ring_info(struct xhci_ring *ring)
+{
+       /* The ring is empty, so the enqueue pointer == dequeue pointer */
+       ring->enqueue = ring->first_seg->trbs;
+       ring->enq_seg = ring->first_seg;
+       ring->dequeue = ring->enqueue;
+       ring->deq_seg = ring->first_seg;
+       /* The ring is initialized to 0. The producer must write 1 to the cycle
+        * bit to handover ownership of the TRB, so PCS = 1.  The consumer must
+        * compare CCS to the cycle bit to check ownership, so CCS = 1.
+        */
+       ring->cycle_state = 1;
+       /* Not necessary for new rings, but needed for re-initialized rings */
+       ring->enq_updates = 0;
+       ring->deq_updates = 0;
+}
+
 /**
  * Create a new ring with zero or more segments.
  *
                                " segment %p (virtual), 0x%llx (DMA)\n",
                                prev, (unsigned long long)prev->dma);
        }
-       /* The ring is empty, so the enqueue pointer == dequeue pointer */
-       ring->enqueue = ring->first_seg->trbs;
-       ring->enq_seg = ring->first_seg;
-       ring->dequeue = ring->enqueue;
-       ring->deq_seg = ring->first_seg;
-       /* The ring is initialized to 0. The producer must write 1 to the cycle
-        * bit to handover ownership of the TRB, so PCS = 1.  The consumer must
-        * compare CCS to the cycle bit to check ownership, so CCS = 1.
-        */
-       ring->cycle_state = 1;
-
+       xhci_initialize_ring_info(ring);
        return ring;
 
 fail:
        return 0;
 }
 
+/* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue
+ * pointers to the beginning of the ring.
+ */
+static void xhci_reinit_cached_ring(struct xhci_hcd *xhci,
+               struct xhci_ring *ring)
+{
+       struct xhci_segment     *seg = ring->first_seg;
+       do {
+               memset(seg->trbs, 0,
+                               sizeof(union xhci_trb)*TRBS_PER_SEGMENT);
+               /* All endpoint rings have link TRBs */
+               xhci_link_segments(xhci, seg, seg->next, 1);
+               seg = seg->next;
+       } while (seg != ring->first_seg);
+       xhci_initialize_ring_info(ring);
+       /* td list should be empty since all URBs have been cancelled,
+        * but just in case...
+        */
+       INIT_LIST_HEAD(&ring->td_list);
+}
+
 #define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32)
 
 struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
                if (dev->eps[i].ring)
                        xhci_ring_free(xhci, dev->eps[i].ring);
 
+       if (dev->ring_cache) {
+               for (i = 0; i < dev->num_rings_cached; i++)
+                       xhci_ring_free(xhci, dev->ring_cache[i]);
+               kfree(dev->ring_cache);
+       }
+
        if (dev->in_ctx)
                xhci_free_container_ctx(xhci, dev->in_ctx);
        if (dev->out_ctx)
        if (!dev->eps[0].ring)
                goto fail;
 
+       /* Allocate pointers to the ring cache */
+       dev->ring_cache = kzalloc(
+                       sizeof(struct xhci_ring *)*XHCI_MAX_RINGS_CACHED,
+                       flags);
+       if (!dev->ring_cache)
+               goto fail;
+       dev->num_rings_cached = 0;
+
        init_completion(&dev->cmd_completion);
        INIT_LIST_HEAD(&dev->cmd_list);
 
        /* Set up the endpoint ring */
        virt_dev->eps[ep_index].new_ring =
                xhci_ring_alloc(xhci, 1, true, mem_flags);
-       if (!virt_dev->eps[ep_index].new_ring)
-               return -ENOMEM;
+       if (!virt_dev->eps[ep_index].new_ring) {
+               /* Attempt to use the ring cache */
+               if (virt_dev->num_rings_cached == 0)
+                       return -ENOMEM;
+               virt_dev->eps[ep_index].new_ring =
+                       virt_dev->ring_cache[virt_dev->num_rings_cached];
+               virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
+               virt_dev->num_rings_cached--;
+               xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring);
+       }
        ep_ring = virt_dev->eps[ep_index].new_ring;
        ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;