提交 3cf7f0c0 编写于 作者: G Greg Kroah-Hartman

Merge branch 'for-usb-linus' of...

Merge branch 'for-usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus

* 'for-usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci:
  xhci: Fix command ring replay after resume.
  xHCI: fix wMaxPacketSize mask
  xHCI: release spinlock when setup interrupt
  xhci: Remove excessive printks with shared IRQs.
...@@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, ...@@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
if (udev->speed == USB_SPEED_SUPER) if (udev->speed == USB_SPEED_SUPER)
return ep->ss_ep_comp.wBytesPerInterval; return ep->ss_ep_comp.wBytesPerInterval;
max_packet = ep->desc.wMaxPacketSize & 0x3ff; max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
/* A 0 in max burst means 1 transfer per ESIT */ /* A 0 in max burst means 1 transfer per ESIT */
return max_packet * (max_burst + 1); return max_packet * (max_burst + 1);
...@@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, ...@@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
/* Fall through */ /* Fall through */
case USB_SPEED_FULL: case USB_SPEED_FULL:
case USB_SPEED_LOW: case USB_SPEED_LOW:
max_packet = ep->desc.wMaxPacketSize & 0x3ff; max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
ep_ctx->ep_info2 |= MAX_PACKET(max_packet); ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
break; break;
default: default:
......
...@@ -2104,7 +2104,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) ...@@ -2104,7 +2104,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
if (!(status & STS_EINT)) { if (!(status & STS_EINT)) {
spin_unlock(&xhci->lock); spin_unlock(&xhci->lock);
xhci_warn(xhci, "Spurious interrupt.\n");
return IRQ_NONE; return IRQ_NONE;
} }
xhci_dbg(xhci, "op reg status = %08x\n", status); xhci_dbg(xhci, "op reg status = %08x\n", status);
......
...@@ -577,6 +577,65 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) ...@@ -577,6 +577,65 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
} }
static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
{
u64 val_64;
/* step 2: initialize command ring buffer */
val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
(xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
xhci->cmd_ring->dequeue) &
(u64) ~CMD_RING_RSVD_BITS) |
xhci->cmd_ring->cycle_state;
xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n",
(long unsigned long) val_64);
xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
}
/*
* The whole command ring must be cleared to zero when we suspend the host.
*
* The host doesn't save the command ring pointer in the suspend well, so we
* need to re-program it on resume. Unfortunately, the pointer must be 64-byte
* aligned, because of the reserved bits in the command ring dequeue pointer
* register. Therefore, we can't just set the dequeue pointer back in the
* middle of the ring (TRBs are 16-byte aligned).
*/
static void xhci_clear_command_ring(struct xhci_hcd *xhci)
{
struct xhci_ring *ring;
struct xhci_segment *seg;
ring = xhci->cmd_ring;
seg = ring->deq_seg;
do {
memset(seg->trbs, 0, SEGMENT_SIZE);
seg = seg->next;
} while (seg != ring->deq_seg);
/* Reset the software enqueue and dequeue pointers */
ring->deq_seg = ring->first_seg;
ring->dequeue = ring->first_seg->trbs;
ring->enq_seg = ring->deq_seg;
ring->enqueue = ring->dequeue;
/*
* Ring is now zeroed, so the HW should look for change of ownership
* when the cycle bit is set to 1.
*/
ring->cycle_state = 1;
/*
* Reset the hardware dequeue pointer.
* Yes, this will need to be re-written after resume, but we're paranoid
* and want to make sure the hardware doesn't access bogus memory
* because, say, the BIOS or an SMI started the host without changing
* the command ring pointers.
*/
xhci_set_cmd_ring_deq(xhci);
}
/* /*
* Stop HC (not bus-specific) * Stop HC (not bus-specific)
* *
...@@ -604,6 +663,7 @@ int xhci_suspend(struct xhci_hcd *xhci) ...@@ -604,6 +663,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
spin_unlock_irq(&xhci->lock); spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
xhci_clear_command_ring(xhci);
/* step 3: save registers */ /* step 3: save registers */
xhci_save_registers(xhci); xhci_save_registers(xhci);
...@@ -635,7 +695,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) ...@@ -635,7 +695,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
u32 command, temp = 0; u32 command, temp = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *hcd = xhci_to_hcd(xhci);
struct pci_dev *pdev = to_pci_dev(hcd->self.controller); struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
u64 val_64;
int old_state, retval; int old_state, retval;
old_state = hcd->state; old_state = hcd->state;
...@@ -648,15 +707,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) ...@@ -648,15 +707,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
/* step 1: restore register */ /* step 1: restore register */
xhci_restore_registers(xhci); xhci_restore_registers(xhci);
/* step 2: initialize command ring buffer */ /* step 2: initialize command ring buffer */
val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); xhci_set_cmd_ring_deq(xhci);
val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
(xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
xhci->cmd_ring->dequeue) &
(u64) ~CMD_RING_RSVD_BITS) |
xhci->cmd_ring->cycle_state;
xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n",
(long unsigned long) val_64);
xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
/* step 3: restore state and start state*/ /* step 3: restore state and start state*/
/* step 3: set CRS flag */ /* step 3: set CRS flag */
command = xhci_readl(xhci, &xhci->op_regs->command); command = xhci_readl(xhci, &xhci->op_regs->command);
...@@ -714,6 +765,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) ...@@ -714,6 +765,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
return retval; return retval;
} }
spin_unlock_irq(&xhci->lock);
/* Re-setup MSI-X */ /* Re-setup MSI-X */
if (hcd->irq) if (hcd->irq)
free_irq(hcd->irq, hcd); free_irq(hcd->irq, hcd);
...@@ -736,6 +788,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) ...@@ -736,6 +788,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
hcd->irq = pdev->irq; hcd->irq = pdev->irq;
} }
spin_lock_irq(&xhci->lock);
/* step 4: set Run/Stop bit */ /* step 4: set Run/Stop bit */
command = xhci_readl(xhci, &xhci->op_regs->command); command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_RUN; command |= CMD_RUN;
......
...@@ -621,6 +621,11 @@ struct xhci_ep_ctx { ...@@ -621,6 +621,11 @@ struct xhci_ep_ctx {
#define MAX_PACKET_MASK (0xffff << 16) #define MAX_PACKET_MASK (0xffff << 16)
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff) #define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
/* Get max packet size from ep desc. Bit 10..0 specify the max packet size.
* USB2.0 spec 9.6.6.
*/
#define GET_MAX_PACKET(p) ((p) & 0x7ff)
/* tx_info bitmasks */ /* tx_info bitmasks */
#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) #define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff)
#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) #define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册