From: Wesley Cheng <quic_wcheng@quicinc.com>
To: <srinivas.kandagatla@linaro.org>, <mathias.nyman@intel.com>,
<perex@perex.cz>, <broonie@kernel.org>, <lgirdwood@gmail.com>,
<krzysztof.kozlowski+dt@linaro.org>, <agross@kernel.org>,
<Thinh.Nguyen@synopsys.com>, <bgoswami@quicinc.com>,
<andersson@kernel.org>, <robh+dt@kernel.org>,
<gregkh@linuxfoundation.org>, <tiwai@suse.com>
Cc: <linux-kernel@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
<alsa-devel@alsa-project.org>, <devicetree@vger.kernel.org>,
<linux-usb@vger.kernel.org>, <quic_jackp@quicinc.com>,
<quic_plai@quicinc.com>,
Mathias Nyman <mathias.nyman@linux.intel.com>,
Wesley Cheng <quic_wcheng@quicinc.com>
Subject: [PATCH v3 01/28] xhci: Add support to allocate several interrupters
Date: Wed, 8 Mar 2023 15:57:24 -0800 [thread overview]
Message-ID: <20230308235751.495-2-quic_wcheng@quicinc.com> (raw)
In-Reply-To: <20230308235751.495-1-quic_wcheng@quicinc.com>
From: Mathias Nyman <mathias.nyman@linux.intel.com>
Introduce xHCI APIs to allow for clients to allocate and free
interrupters. This allocates an array of interrupters, which is based on
the max_interrupters parameter. The primary interrupter is set as the
first entry in the array, and secondary interrupters following after.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
---
drivers/usb/host/xhci-debugfs.c | 2 +-
drivers/usb/host/xhci-mem.c | 97 +++++++++++++++++++++++++++++++--
drivers/usb/host/xhci-ring.c | 2 +-
drivers/usb/host/xhci.c | 51 +++++++++++------
drivers/usb/host/xhci.h | 2 +-
include/linux/usb/xhci-intr.h | 86 +++++++++++++++++++++++++++++
6 files changed, 214 insertions(+), 26 deletions(-)
create mode 100644 include/linux/usb/xhci-intr.h
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index 0bc7fe11f749..06a42b68446f 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -692,7 +692,7 @@ void xhci_debugfs_init(struct xhci_hcd *xhci)
"command-ring",
xhci->debugfs_root);
- xhci_debugfs_create_ring_dir(xhci, &xhci->interrupter->event_ring,
+ xhci_debugfs_create_ring_dir(xhci, &xhci->interrupters[0]->event_ring,
"event-ring",
xhci->debugfs_root);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index d0a9467aa5fc..c303a8e1a33d 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1858,6 +1858,30 @@ xhci_free_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
kfree(ir);
}
+/*
+ * Free a secondary interrupter slot. This will allow for other users to request for
+ * the secondary interrupter in the future.
+ */
+void xhci_remove_secondary_interrupter(struct usb_hcd *hcd, struct xhci_interrupter *ir)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ unsigned int intr_num;
+ unsigned long flags;
+
+ if (!ir || !ir->intr_num || ir->intr_num > xhci->max_interrupters) {
+ xhci_dbg(xhci, "Invalid secondary interrupter, can't remove\n");
+ return;
+ }
+
+ /* fixme, shuld we check xhci->interrupter[intr_num] == ir */
+ intr_num = ir->intr_num;
+ xhci_free_interrupter(xhci, ir);
+ spin_lock_irqsave(&xhci->lock, flags);
+ xhci->interrupters[intr_num] = NULL;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+}
+EXPORT_SYMBOL_GPL(xhci_remove_secondary_interrupter);
+
void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
@@ -1865,8 +1889,15 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
cancel_delayed_work_sync(&xhci->cmd_timer);
- xhci_free_interrupter(xhci, xhci->interrupter);
- xhci->interrupter = NULL;
+ for (i = 1; i < xhci->max_interrupters; i++) {
+ if (xhci->interrupters[i])
+ xhci_remove_secondary_interrupter(xhci_to_hcd(xhci),
+ xhci->interrupters[i]);
+ }
+
+ /* free the primary interrupter, interrupter number 0 */
+ xhci_free_interrupter(xhci, xhci->interrupters[0]);
+ xhci->interrupters[0] = NULL;
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed primary event ring");
if (xhci->cmd_ring)
@@ -1937,6 +1968,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
for (i = 0; i < xhci->num_port_caps; i++)
kfree(xhci->port_caps[i].psi);
kfree(xhci->port_caps);
+ kfree(xhci->interrupters);
xhci->num_port_caps = 0;
xhci->usb2_rhub.ports = NULL;
@@ -1945,6 +1977,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->rh_bw = NULL;
xhci->ext_caps = NULL;
xhci->port_caps = NULL;
+ xhci->interrupters = NULL;
xhci->page_size = 0;
xhci->page_shift = 0;
@@ -2258,7 +2291,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int intr_num, gfp_t flags
return NULL;
}
- if (xhci->interrupter) {
+ if (xhci->interrupters[intr_num]) {
xhci_warn(xhci, "Can't allocate already set up interrupter %d\n", intr_num);
return NULL;
}
@@ -2305,6 +2338,56 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int intr_num, gfp_t flags
return NULL;
}
+/*
+ * Allocate a XHCI secondary interrupter slot. If the user requests a specific intr
+ * number, then check if the slot is available. Otherwise, fetch the first available
+ * entry within the interrupter array.
+ */
+struct xhci_interrupter *
+xhci_create_secondary_interrupter(struct usb_hcd *hcd, int intr_num)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct xhci_interrupter *ir;
+ unsigned int i;
+ unsigned int idx = 0;
+ unsigned long flags;
+
+ if (!xhci->interrupters || intr_num > xhci->max_interrupters)
+ return NULL;
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ /* find available secondary interrupter, interrupter 0 is reserved for primary */
+ if (intr_num > 0) {
+ idx = intr_num;
+ } else {
+ for (i = 1; i < xhci->max_interrupters; i++) {
+ if (xhci->interrupters[i] == NULL) {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ if (idx > 0) {
+ ir = xhci_alloc_interrupter(xhci, idx, GFP_KERNEL);
+ if (!ir) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return NULL;
+ }
+ ir->intr_num = idx;
+ xhci->interrupters[idx] = ir;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ return ir;
+ }
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_warn(xhci, "Can't add new secondary interrupter, max interrupters %d\n",
+ xhci->max_interrupters);
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(xhci_create_secondary_interrupter);
+
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
{
dma_addr_t dma;
@@ -2429,8 +2512,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
/* allocate and set up primary interrupter with an event ring. */
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Allocating primary event ring");
- xhci->interrupter = xhci_alloc_interrupter(xhci, 0, flags);
- if (!xhci->interrupter)
+
+ xhci->interrupters = kcalloc_node(xhci->max_interrupters, sizeof(*xhci->interrupters),
+ flags, dev_to_node(dev));
+
+ xhci->interrupters[0] = xhci_alloc_interrupter(xhci, 0, flags);
+ if (!xhci->interrupters[0])
goto fail;
xhci->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index eb788c60c1c0..445a79f36a60 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3054,7 +3054,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
writel(status, &xhci->op_regs->status);
/* This is the handler of the primary interrupter */
- ir = xhci->interrupter;
+ ir = xhci->interrupters[0];
if (!hcd->msi_enabled) {
u32 irq_pending;
irq_pending = readl(&ir->ir_set->irq_pending);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6183ce8574b1..88435b9cd66e 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -638,7 +638,7 @@ static int xhci_init(struct usb_hcd *hcd)
static int xhci_run_finished(struct xhci_hcd *xhci)
{
- struct xhci_interrupter *ir = xhci->interrupter;
+ struct xhci_interrupter *ir = xhci->interrupters[0];
unsigned long flags;
u32 temp;
@@ -690,7 +690,7 @@ int xhci_run(struct usb_hcd *hcd)
u64 temp_64;
int ret;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- struct xhci_interrupter *ir = xhci->interrupter;
+ struct xhci_interrupter *ir = xhci->interrupters[0];
/* Start the xHCI host controller running only after the USB 2.0 roothub
* is setup.
*/
@@ -758,7 +758,7 @@ static void xhci_stop(struct usb_hcd *hcd)
{
u32 temp;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- struct xhci_interrupter *ir = xhci->interrupter;
+ struct xhci_interrupter *ir = xhci->interrupters[0];
mutex_lock(&xhci->mutex);
@@ -857,36 +857,51 @@ EXPORT_SYMBOL_GPL(xhci_shutdown);
#ifdef CONFIG_PM
static void xhci_save_registers(struct xhci_hcd *xhci)
{
- struct xhci_interrupter *ir = xhci->interrupter;
+ struct xhci_interrupter *ir;
+ unsigned int i;
xhci->s3.command = readl(&xhci->op_regs->command);
xhci->s3.dev_nt = readl(&xhci->op_regs->dev_notification);
xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
xhci->s3.config_reg = readl(&xhci->op_regs->config_reg);
- if (!ir)
- return;
+ /* save both primary and all secondary interrupters */
+ /* fixme, shold we lock to prevent race with remove secondary interrupter? */
+ for (i = 0; i < xhci->max_interrupters; i++) {
+ ir = xhci->interrupters[i];
+ if (!ir)
+ continue;
- ir->s3_erst_size = readl(&ir->ir_set->erst_size);
- ir->s3_erst_base = xhci_read_64(xhci, &ir->ir_set->erst_base);
- ir->s3_erst_dequeue = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
- ir->s3_irq_pending = readl(&ir->ir_set->irq_pending);
- ir->s3_irq_control = readl(&ir->ir_set->irq_control);
+ ir->s3_erst_size = readl(&ir->ir_set->erst_size);
+ ir->s3_erst_base = xhci_read_64(xhci, &ir->ir_set->erst_base);
+ ir->s3_erst_dequeue = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
+ ir->s3_irq_pending = readl(&ir->ir_set->irq_pending);
+ ir->s3_irq_control = readl(&ir->ir_set->irq_control);
+ }
}
static void xhci_restore_registers(struct xhci_hcd *xhci)
{
- struct xhci_interrupter *ir = xhci->interrupter;
+ struct xhci_interrupter *ir;
+ unsigned int i;
writel(xhci->s3.command, &xhci->op_regs->command);
writel(xhci->s3.dev_nt, &xhci->op_regs->dev_notification);
xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr);
writel(xhci->s3.config_reg, &xhci->op_regs->config_reg);
- writel(ir->s3_erst_size, &ir->ir_set->erst_size);
- xhci_write_64(xhci, ir->s3_erst_base, &ir->ir_set->erst_base);
- xhci_write_64(xhci, ir->s3_erst_dequeue, &ir->ir_set->erst_dequeue);
- writel(ir->s3_irq_pending, &ir->ir_set->irq_pending);
- writel(ir->s3_irq_control, &ir->ir_set->irq_control);
+
+ /* FIXME should we lock to protect against freeing of interrupters */
+ for (i = 0; i < xhci->max_interrupters; i++) {
+ ir = xhci->interrupters[i];
+ if (!ir)
+ continue;
+
+ writel(ir->s3_erst_size, &ir->ir_set->erst_size);
+ xhci_write_64(xhci, ir->s3_erst_base, &ir->ir_set->erst_base);
+ xhci_write_64(xhci, ir->s3_erst_dequeue, &ir->ir_set->erst_dequeue);
+ writel(ir->s3_irq_pending, &ir->ir_set->irq_pending);
+ writel(ir->s3_irq_control, &ir->ir_set->irq_control);
+ }
}
static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
@@ -1251,7 +1266,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
xhci_dbg(xhci, "// Disabling event ring interrupts\n");
temp = readl(&xhci->op_regs->status);
writel((temp & ~0x1fff) | STS_EINT, &xhci->op_regs->status);
- xhci_disable_interrupter(xhci->interrupter);
+ xhci_disable_interrupter(xhci->interrupters[0]);
xhci_dbg(xhci, "cleaning up memory\n");
xhci_mem_cleanup(xhci);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 786002bb35db..43118ce83cca 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1800,7 +1800,7 @@ struct xhci_hcd {
struct reset_control *reset;
/* data structures */
struct xhci_device_context_array *dcbaa;
- struct xhci_interrupter *interrupter;
+ struct xhci_interrupter **interrupters;
struct xhci_ring *cmd_ring;
unsigned int cmd_ring_state;
#define CMD_RING_STATE_RUNNING (1 << 0)
diff --git a/include/linux/usb/xhci-intr.h b/include/linux/usb/xhci-intr.h
new file mode 100644
index 000000000000..738b0f0481a6
--- /dev/null
+++ b/include/linux/usb/xhci-intr.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_XHCI_INTR_H
+#define __LINUX_XHCI_INTR_H
+
+#include <linux/kernel.h>
+
+struct xhci_erst_entry {
+ /* 64-bit event ring segment address */
+ __le64 seg_addr;
+ __le32 seg_size;
+ /* Set to zero */
+ __le32 rsvd;
+};
+
+enum xhci_ring_type {
+ TYPE_CTRL = 0,
+ TYPE_ISOC,
+ TYPE_BULK,
+ TYPE_INTR,
+ TYPE_STREAM,
+ TYPE_COMMAND,
+ TYPE_EVENT,
+};
+
+struct xhci_erst {
+ struct xhci_erst_entry *entries;
+ unsigned int num_entries;
+ /* xhci->event_ring keeps track of segment dma addresses */
+ dma_addr_t erst_dma_addr;
+ /* Num entries the ERST can contain */
+ unsigned int erst_size;
+};
+
+struct xhci_segment {
+ union xhci_trb *trbs;
+ /* private to HCD */
+ struct xhci_segment *next;
+ dma_addr_t dma;
+ /* Max packet sized bounce buffer for td-fragmant alignment */
+ dma_addr_t bounce_dma;
+ void *bounce_buf;
+ unsigned int bounce_offs;
+ unsigned int bounce_len;
+};
+
+struct xhci_ring {
+ struct xhci_segment *first_seg;
+ struct xhci_segment *last_seg;
+ union xhci_trb *enqueue;
+ struct xhci_segment *enq_seg;
+ union xhci_trb *dequeue;
+ struct xhci_segment *deq_seg;
+ struct list_head td_list;
+ /*
+ * Write the cycle state into the TRB cycle field to give ownership of
+ * the TRB to the host controller (if we are the producer), or to check
+ * if we own the TRB (if we are the consumer). See section 4.9.1.
+ */
+ u32 cycle_state;
+ unsigned int stream_id;
+ unsigned int num_segs;
+ unsigned int num_trbs_free;
+ unsigned int num_trbs_free_temp;
+ unsigned int bounce_buf_len;
+ enum xhci_ring_type type;
+ bool last_td_was_short;
+ struct radix_tree_root *trb_address_map;
+};
+
+struct xhci_interrupter {
+ struct xhci_ring *event_ring;
+ struct xhci_erst erst;
+ struct xhci_intr_reg __iomem *ir_set;
+ unsigned int intr_num;
+ /* For interrupter registers save and restore over suspend/resume */
+ u32 s3_irq_pending;
+ u32 s3_irq_control;
+ u32 s3_erst_size;
+ u64 s3_erst_base;
+ u64 s3_erst_dequeue;
+};
+
+struct xhci_interrupter *
+xhci_create_secondary_interrupter(struct usb_hcd *hcd, int intr_num);
+void xhci_remove_secondary_interrupter(struct usb_hcd *hcd, struct xhci_interrupter *ir);
+#endif
next prev parent reply other threads:[~2023-03-08 23:58 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-08 23:57 [PATCH v3 00/28] Introduce QC USB SND audio offloading support Wesley Cheng
2023-03-08 23:57 ` Wesley Cheng [this message]
2023-03-09 10:34 ` [PATCH v3 01/28] xhci: Add support to allocate several interrupters Oliver Neukum
2023-03-09 10:51 ` Takashi Iwai
2023-03-10 15:07 ` Mathias Nyman
2023-03-13 20:08 ` Wesley Cheng
2023-04-25 1:17 ` Wesley Cheng
2023-03-13 20:32 ` Wesley Cheng
2023-06-23 22:37 ` Wesley Cheng
2023-06-26 13:55 ` Mathias Nyman
2023-06-26 15:05 ` Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 02/28] usb: xhci: Add XHCI APIs to support USB offloading Wesley Cheng
2023-03-09 6:38 ` Greg KH
2023-03-09 19:51 ` Wesley Cheng
2023-03-10 12:17 ` Claudiu.Beznea
2023-03-08 23:57 ` [PATCH v3 03/28] usb: host: xhci-mem: Cleanup pending secondary event ring events Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 04/28] ASoC: Add SOC USB APIs for adding an USB backend Wesley Cheng
2023-03-09 6:41 ` Greg KH
2023-03-08 23:57 ` [PATCH v3 05/28] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add USB_RX port Wesley Cheng
2023-03-09 9:00 ` Srinivas Kandagatla
2023-03-08 23:57 ` [PATCH v3 06/28] ASoC: qcom: qdsp6: Introduce USB AFE port to q6dsp Wesley Cheng
2023-03-09 9:01 ` Srinivas Kandagatla
2023-03-08 23:57 ` [PATCH v3 07/28] ASoC: qdsp6: q6afe: Increase APR timeout Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 08/28] ASoC: qcom: Add USB backend ASoC driver for Q6 Wesley Cheng
2023-03-09 9:01 ` Srinivas Kandagatla
2023-03-09 19:38 ` Wesley Cheng
2023-03-10 7:21 ` Srinivas Kandagatla
2023-03-25 1:15 ` Wesley Cheng
2023-03-10 12:22 ` Claudiu.Beznea
2023-03-08 23:57 ` [PATCH v3 09/28] sound: usb: card: Introduce USB SND platform op callbacks Wesley Cheng
2023-03-09 6:44 ` Greg KH
2023-03-09 14:10 ` Takashi Iwai
2023-03-09 11:16 ` Oliver Neukum
2023-03-08 23:57 ` [PATCH v3 10/28] sound: usb: Export USB SND APIs for modules Wesley Cheng
2023-03-09 6:29 ` Greg KH
2023-03-08 23:57 ` [PATCH v3 11/28] dt-bindings: usb: dwc3: Add snps,num-hc-interrupters definition Wesley Cheng
2023-03-10 8:50 ` Krzysztof Kozlowski
2023-03-11 13:40 ` Rob Herring
2023-08-29 2:05 ` Wesley Cheng
2023-08-29 6:33 ` Krzysztof Kozlowski
2023-08-29 7:19 ` Wesley Cheng
2023-08-29 7:42 ` Krzysztof Kozlowski
2023-08-29 7:50 ` Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 12/28] usb: dwc3: Add DT parameter to specify maximum number of interrupters Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 13/28] usb: host: xhci-plat: Set XHCI max interrupters if property is present Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 14/28] sound: usb: pcm: Export fixed rate check USB SND API Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 15/28] sound: usb: Introduce QC USB SND offloading support Wesley Cheng
2023-03-09 8:29 ` Takashi Sakamoto
2023-03-09 17:54 ` Pierre-Louis Bossart
2023-03-08 23:57 ` [PATCH v3 16/28] sound: usb: card: Check for support for requested audio format Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 17/28] sound: soc: soc-usb: Add PCM format check API for USB backend Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 18/28] sound: soc: qcom: qusb6: Ensure PCM format is supported by USB audio device Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 19/28] sound: usb: Prevent starting of audio stream if in use Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 20/28] ASoC: dt-bindings: Add Q6USB backend bindings Wesley Cheng
2023-03-10 8:54 ` Krzysztof Kozlowski
2023-06-23 0:15 ` Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 21/28] ASoC: dt-bindings: Update example for enabling USB offload on SM8250 Wesley Cheng
2023-03-10 8:56 ` Krzysztof Kozlowski
2023-06-23 0:51 ` Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 22/28] ASoC: qcom: qdsp6: q6afe: Split USB AFE dev_token param into separate API Wesley Cheng
2023-03-09 9:01 ` Srinivas Kandagatla
2023-03-09 19:39 ` Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 23/28] sound: Pass USB SND card and PCM information to SOC USB Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 24/28] sound: soc: qdsp6: Add SND kcontrol to select offload device Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 25/28] sound: soc: qdsp6: Add SND kcontrol for fetching offload status Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 26/28] sound: usb: qc_audio_offload: Use card and PCM index from QMI request Wesley Cheng
2023-03-08 23:57 ` [PATCH v3 27/28] sound: usb: card: Allow for rediscovery of connected USB SND devices Wesley Cheng
2023-03-09 11:32 ` Oliver Neukum
2023-03-08 23:57 ` [PATCH v3 28/28] sound: soc: soc-usb: Rediscover USB SND devices on USB port add Wesley Cheng
2023-03-09 6:46 ` [PATCH v3 00/28] Introduce QC USB SND audio offloading support Greg KH
2023-03-09 17:13 ` Pierre-Louis Bossart
2023-03-09 21:10 ` Wesley Cheng
2023-03-10 0:37 ` Pierre-Louis Bossart
2023-03-13 23:43 ` Wesley Cheng
2023-03-14 0:42 ` Pierre-Louis Bossart
2023-03-14 1:42 ` Wesley Cheng
2023-03-14 2:22 ` Pierre-Louis Bossart
2023-03-15 0:08 ` Wesley Cheng
2023-03-15 14:30 ` Pierre-Louis Bossart
2023-03-15 16:29 ` Mark Brown
2023-03-15 19:42 ` 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=20230308235751.495-2-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=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=lgirdwood@gmail.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=mathias.nyman@linux.intel.com \
--cc=perex@perex.cz \
--cc=quic_jackp@quicinc.com \
--cc=quic_plai@quicinc.com \
--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