mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Wesley Cheng <quic_wcheng@quicinc.com>
To: <srinivas.kandagatla@linaro.org>, <mathias.nyman@intel.com>,
	<perex@perex.cz>, <conor+dt@kernel.org>, <corbet@lwn.net>,
	<gregkh@linuxfoundation.org>, <lgirdwood@gmail.com>,
	<andersson@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>,
	<konrad.dybcio@linaro.org>, <Thinh.Nguyen@synopsys.com>,
	<broonie@kernel.org>, <bgoswami@quicinc.com>, <tiwai@suse.com>,
	<robh+dt@kernel.org>, <agross@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-sound@vger.kernel.org>, <linux-usb@vger.kernel.org>,
	<linux-arm-msm@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<alsa-devel@alsa-project.org>,
	Wesley Cheng <quic_wcheng@quicinc.com>
Subject: [PATCH v10 04/41] usb: host: xhci-mem: Cleanup pending secondary event ring events
Date: Fri, 15 Dec 2023 13:49:18 -0800	[thread overview]
Message-ID: <20231215214955.12110-5-quic_wcheng@quicinc.com> (raw)
In-Reply-To: <20231215214955.12110-1-quic_wcheng@quicinc.com>

As part of xHCI bus suspend, the XHCI is halted.  However, if there are
pending events in the secondary event ring, it is observed that the xHCI
controller stops responding to further commands upon host or device
initiated bus resume.  Iterate through all pending events and update the
dequeue pointer to the beginning of the event ring.

Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
---
 drivers/usb/host/xhci-mem.c  | 11 +++++----
 drivers/usb/host/xhci-ring.c | 46 +++++++++++++++++++++++++++++++++++-
 drivers/usb/host/xhci.c      |  2 +-
 drivers/usb/host/xhci.h      |  7 ++++++
 4 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 4460fa7e9fab..5bf74c37cbf6 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1827,7 +1827,7 @@ xhci_remove_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
 		tmp &= ERST_SIZE_MASK;
 		writel(tmp, &ir->ir_set->erst_size);
 
-		xhci_write_64(xhci, ERST_EHB, &ir->ir_set->erst_dequeue);
+		xhci_update_erst_dequeue(xhci, ir, ir->event_ring->first_seg->trbs, true);
 	}
 }
 
@@ -1865,11 +1865,12 @@ void xhci_remove_secondary_interrupter(struct usb_hcd *hcd, struct xhci_interrup
 	if (!ir || !ir->intr_num || ir->intr_num >= xhci->max_interrupters)
 		xhci_dbg(xhci, "Invalid secondary interrupter, can't remove\n");
 
-	/* fixme, should we check xhci->interrupter[intr_num] == ir */
-	/* fixme locking */
-
 	spin_lock_irq(&xhci->lock);
-
+	/*
+	 * Cleanup secondary interrupter to ensure there are no pending events.
+	 * This also updates event ring dequeue pointer back to the start.
+	 */
+	xhci_skip_sec_intr_events(xhci, ir->event_ring, ir);
 	intr_num = ir->intr_num;
 
 	xhci_remove_interrupter(xhci, ir);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 33806ae966f9..448417c5d5b1 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2980,7 +2980,7 @@ static int xhci_handle_event(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
  * - When all events have finished
  * - To avoid "Event Ring Full Error" condition
  */
-static void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
+void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
 				     struct xhci_interrupter *ir,
 				     union xhci_trb *event_ring_deq,
 				     bool clear_ehb)
@@ -3013,6 +3013,50 @@ static void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
 	xhci_write_64(xhci, temp_64, &ir->ir_set->erst_dequeue);
 }
 
+/*
+ * Move the event ring dequeue pointer to skip events kept in the secondary
+ * event ring.  This is used to ensure that pending events in the ring are
+ * acknowledged, so the XHCI HCD can properly enter suspend/resume.  The
+ * secondary ring is typically maintained by an external component.
+ */
+void xhci_skip_sec_intr_events(struct xhci_hcd *xhci,
+	struct xhci_ring *ring,	struct xhci_interrupter *ir)
+{
+	union xhci_trb *erdp_trb, *current_trb;
+	u64 erdp_reg;
+	u32 iman_reg;
+	dma_addr_t deq;
+
+	/* disable irq, ack pending interrupt and ack all pending events */
+	xhci_disable_interrupter(ir);
+	iman_reg = readl_relaxed(&ir->ir_set->irq_pending);
+	if (iman_reg & IMAN_IP)
+		writel_relaxed(iman_reg, &ir->ir_set->irq_pending);
+
+	/* last acked event trb is in erdp reg  */
+	erdp_reg = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
+	deq = (dma_addr_t)(erdp_reg & ERST_PTR_MASK);
+	if (!deq) {
+		xhci_err(xhci, "event ring handling not required\n");
+		return;
+	}
+
+	erdp_trb = current_trb = ir->event_ring->dequeue;
+	/* read cycle state of the last acked trb to find out CCS */
+	ring->cycle_state = le32_to_cpu(current_trb->event_cmd.flags) & TRB_CYCLE;
+
+	while (1) {
+		inc_deq(xhci, ir->event_ring);
+		erdp_trb = ir->event_ring->dequeue;
+		/* cycle state transition */
+		if ((le32_to_cpu(erdp_trb->event_cmd.flags) & TRB_CYCLE) !=
+		    ring->cycle_state)
+			break;
+	}
+
+	xhci_update_erst_dequeue(xhci, ir, current_trb, true);
+}
+
 /*
  * xHCI spec says we can get an interrupt, and if the HC has an error condition,
  * we might get bad data out of the event ring.  Section 4.10.2.7 has a list of
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index fd7d06f6fe36..f9d3d556a2d7 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -333,7 +333,7 @@ static int xhci_enable_interrupter(struct xhci_interrupter *ir)
 	return 0;
 }
 
-static int xhci_disable_interrupter(struct xhci_interrupter *ir)
+int xhci_disable_interrupter(struct xhci_interrupter *ir)
 {
 	u32 iman;
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index e98099b960e4..37887c2f0653 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2093,6 +2093,9 @@ struct xhci_interrupter *
 xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg);
 void xhci_remove_secondary_interrupter(struct usb_hcd
 				       *hcd, struct xhci_interrupter *ir);
+void xhci_skip_sec_intr_events(struct xhci_hcd *xhci,
+	struct xhci_ring *ring,	struct xhci_interrupter *ir);
+int xhci_disable_interrupter(struct xhci_interrupter *ir);
 
 /* xHCI host controller glue */
 typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
@@ -2180,6 +2183,10 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring);
 unsigned int count_trbs(u64 addr, u64 len);
 int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
 			    int suspend, gfp_t gfp_flags);
+void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
+				     struct xhci_interrupter *ir,
+				     union xhci_trb *event_ring_deq,
+				     bool clear_ehb);
 
 /* xHCI roothub code */
 void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,

  parent reply	other threads:[~2023-12-15 21:50 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-15 21:49 [PATCH v10 00/41] Introduce QC USB SND audio offloading support Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 01/41] xhci: add support to allocate several interrupters Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 02/41] xhci: add helper to stop endpoint and wait for completion Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 03/41] xhci: sideband: add initial api to register a sideband entity Wesley Cheng
2023-12-15 21:49 ` Wesley Cheng [this message]
2023-12-15 21:49 ` [PATCH v10 05/41] usb: host: xhci-mem: Allow for interrupter clients to choose specific index Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 06/41] ASoC: Add SOC USB APIs for adding an USB backend Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 07/41] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add USB_RX port Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 08/41] ASoC: qcom: qdsp6: Introduce USB AFE port to q6dsp Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 09/41] ASoC: qdsp6: q6afe: Increase APR timeout Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 10/41] ASoC: qcom: qdsp6: Add USB backend ASoC driver for Q6 Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 11/41] ALSA: usb-audio: Introduce USB SND platform op callbacks Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 12/41] ALSA: usb-audio: Export USB SND APIs for modules Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 13/41] ALSA: usb-audio: Save UAC sample size information Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 14/41] dt-bindings: usb: xhci: Add num-hc-interrupters definition Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 15/41] dt-bindings: usb: dwc3: Limit " Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 16/41] usb: dwc3: Specify maximum number of XHCI interrupters Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 17/41] usb: host: xhci-plat: Set XHCI max interrupters if property is present Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 18/41] ALSA: usb-audio: qcom: Add USB QMI definitions Wesley Cheng
2023-12-15 22:38   ` Jeff Johnson
2023-12-18 19:58     ` Wesley Cheng
2023-12-19 12:01   ` Konrad Dybcio
2023-12-19 12:01     ` Konrad Dybcio
2023-12-15 21:49 ` [PATCH v10 19/41] ALSA: usb-audio: qcom: Introduce QC USB SND offloading support Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 20/41] ALSA: usb-audio: Check for support for requested audio format Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 21/41] ASoC: usb: Add PCM format check API for USB backend Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 22/41] ASoC: qcom: qdsp6: Ensure PCM format is supported by USB audio device Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 23/41] ALSA: usb-audio: Prevent starting of audio stream if in use Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 24/41] ALSA: usb-audio: Do not allow USB offload path if PCM device is " Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 25/41] ASoC: dt-bindings: Add Q6USB backend Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 26/41] ASoC: dt-bindings: Update example for enabling USB offload on SM8250 Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 27/41] ALSA: usb-audio: qcom: Populate PCM and USB chip information Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 28/41] ASoC: qcom: qdsp6: Add support to track available USB PCM devices Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 29/41] ASoC: Introduce SND kcontrols to select sound card and PCM device Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 30/41] ASoC: qcom: qdsp6: Add SOC USB offload select get/put callbacks Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 31/41] ASoC: Add SND kcontrol for fetching USB offload status Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 32/41] ASoC: qcom: qdsp6: Add PCM ops to track current state Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 33/41] ASoC: usb: Create SOC USB SND jack kcontrol Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 34/41] ASoC: qcom: qdsp6: Add headphone jack for offload connection status Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 35/41] ASoC: usb: Fetch ASoC sound card information Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 36/41] ALSA: usb-audio: mixer: Add USB offloading mixer control Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 37/41] ALSA: usb-audio: qcom: Use card and PCM index from QMI request Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 38/41] ALSA: usb-audio: Allow for rediscovery of connected USB SND devices Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 39/41] ASoC: usb: Rediscover USB SND devices on USB port add Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 40/41] ASoC: qcom: Populate SoC components string Wesley Cheng
2023-12-15 21:49 ` [PATCH v10 41/41] ASoC: doc: Add documentation for SOC USB Wesley Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231215214955.12110-5-quic_wcheng@quicinc.com \
    --to=quic_wcheng@quicinc.com \
    --cc=Thinh.Nguyen@synopsys.com \
    --cc=agross@kernel.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=andersson@kernel.org \
    --cc=bgoswami@quicinc.com \
    --cc=broonie@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=perex@perex.cz \
    --cc=robh+dt@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®