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

Commit cffd7507 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Revert "usb: xhci-msm-hsic: Reset transfer ring upon bus suspend""

parents 11a4be75 5811b59f
Loading
Loading
Loading
Loading
+0 −79
Original line number Diff line number Diff line
@@ -259,83 +259,6 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
	return slot_id;
}

/*
 * For ep 0 to 30 it resets sw enq and deq pointers to the first seg trb of the
 * ring and issues set tr deq cmd to reset hw deq pointers to the first seg trb
 * of the ring. And wait for the last command to complete.
 */
static int xhci_reset_xfer_ring(struct xhci_hcd *xhci, int slot_id)
{
	struct xhci_virt_device *virt_dev;
	struct xhci_virt_ep *ep;
	struct xhci_dequeue_state deq_state;
	struct xhci_ep_ctx *ep_ctx;
	struct xhci_command *cmd;
	unsigned long flags;
	unsigned int ep_state;
	int i;
	int timeleft;
	int ret;

	virt_dev = xhci->devs[slot_id];
	cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
	if (!cmd) {
		xhci_dbg(xhci, "Couldn't allocate command structure.\n");
		return -ENOMEM;
	}

	spin_lock_irqsave(&xhci->lock, flags);
	for (i = LAST_EP_INDEX; i >= 0; i--) {
		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->out_ctx, i);
		ep_state = ep_ctx->ep_info & cpu_to_le32(EP_STATE_MASK);
		ep = &virt_dev->eps[i];
		if (ep->ring && ep->ring->dequeue
			&& ep_state == cpu_to_le32(EP_STATE_STOPPED)
			&& ep->ring->enqueue != ep->ring->dequeue) {
			ep->stopped_td = NULL;
			ep->stopped_trb = NULL;
			xhci_reinit_cached_ring(xhci, ep->ring, 1,
					ep->ring->type);
			memset(&deq_state, 0, sizeof(deq_state));
			deq_state.new_deq_ptr = ep->ring->first_seg->trbs;
			deq_state.new_deq_seg = ep->ring->first_seg;
			deq_state.new_cycle_state = 0x1;
			cmd->command_trb =
				xhci_find_next_enqueue(xhci->cmd_ring);
			xhci_queue_new_dequeue_state(xhci,
				slot_id, i, ep->ring->stream_id,
				&deq_state);
		}
	}

	if (!cmd->command_trb) {
		spin_unlock_irqrestore(&xhci->lock, flags);
		goto command_cleanup;
	}

	list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list);
	xhci_ring_cmd_db(xhci);
	spin_unlock_irqrestore(&xhci->lock, flags);

	/* Wait for last set tr deq command to finish */
	timeleft = wait_for_completion_interruptible_timeout(
			cmd->completion,
			XHCI_CMD_DEFAULT_TIMEOUT);
	if (timeleft <= 0) {
		xhci_warn(xhci, "%s while waiting for set tr deq command\n",
				timeleft == 0 ? "Timeout" : "Signal");
		spin_lock_irqsave(&xhci->lock, flags);
		if (cmd->cmd_list.next != LIST_POISON1)
			list_del(&cmd->cmd_list);
		spin_unlock_irqrestore(&xhci->lock, flags);
		ret = -ETIME;
	}

command_cleanup:
	xhci_free_command(xhci, cmd);
	return ret;
}

/*
 * Stop device
 * It issues stop endpoint command for EP 0 to 30. And wait the last command
@@ -1334,8 +1257,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
					port_index + 1);
			if (slot_id) {
				spin_unlock_irqrestore(&xhci->lock, flags);
				if (xhci->quirks & XHCI_TR_DEQ_RESET_QUIRK)
					xhci_reset_xfer_ring(xhci, slot_id);
				xhci_stop_device(xhci, slot_id, 1);
				spin_lock_irqsave(&xhci->lock, flags);
			}
+1 −1
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci,
/* Zero an endpoint ring (except for link TRBs) and move the enqueue and dequeue
 * pointers to the beginning of the ring.
 */
void xhci_reinit_cached_ring(struct xhci_hcd *xhci,
static void xhci_reinit_cached_ring(struct xhci_hcd *xhci,
			struct xhci_ring *ring, unsigned int cycle_state,
			enum xhci_ring_type type)
{
+0 −7
Original line number Diff line number Diff line
@@ -467,13 +467,6 @@ static void mxhci_hsic_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
	if (mxhci->wakeup_irq)
		xhci->quirks |= XHCI_NO_SELECTIVE_SUSPEND;

	/*
	 * Observing hw tr deq pointer getting stuck to a noop trb
	 * when aborting transfer during suspend. Reset tr deq pointer
	 * to start of the first seg of the xfer ring.
	 */
	xhci->quirks |= XHCI_TR_DEQ_RESET_QUIRK;

	if (!pdata)
		return;
	if (pdata->vendor == SYNOPSIS_DWC3_VENDOR &&
+0 −3
Original line number Diff line number Diff line
@@ -1146,9 +1146,6 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
	dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
	dev->eps[ep_index].queued_deq_seg = NULL;
	dev->eps[ep_index].queued_deq_ptr = NULL;

	handle_cmd_in_cmd_wait_list(xhci, dev, event);

	/* Restart any rings with pending URBs */
	ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
}
+0 −4
Original line number Diff line number Diff line
@@ -1553,7 +1553,6 @@ struct xhci_hcd {
 */
#define XHCI_TR_DEQ_ERR_QUIRK	(1 << 19)
#define XHCI_NO_SELECTIVE_SUSPEND (1 << 20)
#define XHCI_TR_DEQ_RESET_QUIRK   (1 << 21)
/*
 * The DWC_usb3 controller has an internal bus interval counter for tracking the
 * microframes. The following is the expected behavior of the counter: If all of
@@ -1750,9 +1749,6 @@ void xhci_slot_copy(struct xhci_hcd *xhci,
int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev,
		struct usb_device *udev, struct usb_host_endpoint *ep,
		gfp_t mem_flags);
void xhci_reinit_cached_ring(struct xhci_hcd *xhci,
			struct xhci_ring *ring, unsigned int cycle_state,
			enum xhci_ring_type type);
void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring);
int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
				unsigned int num_trbs, gfp_t flags);