Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cf7f0c0 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

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.
parents 0143832c 89821320
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
	if (udev->speed == USB_SPEED_SUPER)
		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;
	/* A 0 in max burst means 1 transfer per ESIT */
	return max_packet * (max_burst + 1);
@@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
		/* Fall through */
	case USB_SPEED_FULL:
	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);
		break;
	default:
+0 −1
Original line number Diff line number Diff line
@@ -2104,7 +2104,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)

	if (!(status & STS_EINT)) {
		spin_unlock(&xhci->lock);
		xhci_warn(xhci, "Spurious interrupt.\n");
		return IRQ_NONE;
	}
	xhci_dbg(xhci, "op reg status = %08x\n", status);
+63 −10
Original line number Diff line number Diff line
@@ -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);
}

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)
 *
@@ -604,6 +663,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
		spin_unlock_irq(&xhci->lock);
		return -ETIMEDOUT;
	}
	xhci_clear_command_ring(xhci);

	/* step 3: save registers */
	xhci_save_registers(xhci);
@@ -635,7 +695,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
	u32			command, temp = 0;
	struct usb_hcd		*hcd = xhci_to_hcd(xhci);
	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
	u64	val_64;
	int	old_state, retval;

	old_state = hcd->state;
@@ -648,15 +707,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
		/* step 1: restore register */
		xhci_restore_registers(xhci);
		/* 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);
		xhci_set_cmd_ring_deq(xhci);
		/* step 3: restore state and start state*/
		/* step 3: set CRS flag */
		command = xhci_readl(xhci, &xhci->op_regs->command);
@@ -714,6 +765,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
		return retval;
	}

	spin_unlock_irq(&xhci->lock);
	/* Re-setup MSI-X */
	if (hcd->irq)
		free_irq(hcd->irq, hcd);
@@ -736,6 +788,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
		hcd->irq = pdev->irq;
	}

	spin_lock_irq(&xhci->lock);
	/* step 4: set Run/Stop bit */
	command = xhci_readl(xhci, &xhci->op_regs->command);
	command |= CMD_RUN;
+5 −0
Original line number Diff line number Diff line
@@ -621,6 +621,11 @@ struct xhci_ep_ctx {
#define MAX_PACKET_MASK		(0xffff << 16)
#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 */
#define AVG_TRB_LENGTH_FOR_EP(p)	((p) & 0xffff)
#define MAX_ESIT_PAYLOAD_FOR_EP(p)	(((p) & 0xffff) << 16)