--- /dev/null
+From ec3cfd835f7c4bbd23bc9ad909d2fdc772a578bb Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 6 Mar 2026 09:24:46 +0200
+Subject: i3c: mipi-i3c-hci: Add missing TID field to no-op command descriptor
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit ec3cfd835f7c4bbd23bc9ad909d2fdc772a578bb upstream.
+
+The internal control command descriptor used for no-op commands includes a
+Transaction ID (TID) field, but the no-op command constructed in
+hci_dma_dequeue_xfer() omitted it. As a result, the hardware receives a
+no-op descriptor without the expected TID.
+
+This bug has gone unnoticed because the TID is currently not validated in
+the no-op completion path, but the descriptor format requires it to be
+present.
+
+Add the missing TID field when generating a no-op descriptor so that its
+layout matches the defined command structure.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-10-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/cmd.h | 1 +
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/i3c/master/mipi-i3c-hci/cmd.h
++++ b/drivers/i3c/master/mipi-i3c-hci/cmd.h
+@@ -17,6 +17,7 @@
+ #define CMD_0_TOC W0_BIT_(31)
+ #define CMD_0_ROC W0_BIT_(30)
+ #define CMD_0_ATTR W0_MASK(2, 0)
++#define CMD_0_TID W0_MASK(6, 3)
+
+ /*
+ * Response Descriptor Structure
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -510,7 +510,7 @@ static bool hci_dma_dequeue_xfer(struct
+ u32 *ring_data = rh->xfer + rh->xfer_struct_sz * idx;
+
+ /* store no-op cmd descriptor */
+- *ring_data++ = FIELD_PREP(CMD_0_ATTR, 0x7);
++ *ring_data++ = FIELD_PREP(CMD_0_ATTR, 0x7) | FIELD_PREP(CMD_0_TID, xfer->cmd_tid);
+ *ring_data++ = 0;
+ if (hci->cmd == &mipi_i3c_hci_cmd_v2) {
+ *ring_data++ = 0;
--- /dev/null
+From fa12bb903bc3ed1826e355d267fe134bde95e23c Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 6 Mar 2026 09:24:41 +0200
+Subject: i3c: mipi-i3c-hci: Consolidate spinlocks
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit fa12bb903bc3ed1826e355d267fe134bde95e23c upstream.
+
+The MIPI I3C HCI driver currently uses separate spinlocks for different
+contexts (PIO vs. DMA rings). This split is unnecessary and complicates
+upcoming fixes. The driver does not support concurrent PIO and DMA
+operation, and it only supports a single DMA ring, so a single lock is
+sufficient for all paths.
+
+Introduce a unified spinlock in struct i3c_hci, switch both PIO and DMA
+code to use it, and remove the per-context locks.
+
+No functional change is intended in this patch.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-5-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/core.c | 2 ++
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 14 ++++++--------
+ drivers/i3c/master/mipi-i3c-hci/hci.h | 1 +
+ drivers/i3c/master/mipi-i3c-hci/pio.c | 16 +++++++---------
+ 4 files changed, 16 insertions(+), 17 deletions(-)
+
+--- a/drivers/i3c/master/mipi-i3c-hci/core.c
++++ b/drivers/i3c/master/mipi-i3c-hci/core.c
+@@ -631,6 +631,8 @@ static int i3c_hci_init(struct i3c_hci *
+ if (ret)
+ return ret;
+
++ spin_lock_init(&hci->lock);
++
+ /*
+ * Now let's reset the hardware.
+ * SOFT_RST must be clear before we write to it.
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -133,7 +133,6 @@ struct hci_rh_data {
+ unsigned int xfer_struct_sz, resp_struct_sz, ibi_status_sz, ibi_chunk_sz;
+ unsigned int done_ptr, ibi_chunk_ptr;
+ struct hci_xfer **src_xfers;
+- spinlock_t lock;
+ struct completion op_done;
+ };
+
+@@ -240,7 +239,6 @@ static int hci_dma_init(struct i3c_hci *
+ goto err_out;
+ rh = &rings->headers[i];
+ rh->regs = hci->base_regs + offset;
+- spin_lock_init(&rh->lock);
+ init_completion(&rh->op_done);
+
+ rh->xfer_entries = XFER_RING_ENTRIES;
+@@ -470,12 +468,12 @@ static int hci_dma_queue_xfer(struct i3c
+ }
+
+ /* take care to update the hardware enqueue pointer atomically */
+- spin_lock_irq(&rh->lock);
++ spin_lock_irq(&hci->lock);
+ op1_val = rh_reg_read(RING_OPERATION1);
+ op1_val &= ~RING_OP1_CR_ENQ_PTR;
+ op1_val |= FIELD_PREP(RING_OP1_CR_ENQ_PTR, enqueue_ptr);
+ rh_reg_write(RING_OPERATION1, op1_val);
+- spin_unlock_irq(&rh->lock);
++ spin_unlock_irq(&hci->lock);
+
+ return 0;
+ }
+@@ -573,12 +571,12 @@ static void hci_dma_xfer_done(struct i3c
+ }
+
+ /* take care to update the software dequeue pointer atomically */
+- spin_lock(&rh->lock);
++ spin_lock(&hci->lock);
+ op1_val = rh_reg_read(RING_OPERATION1);
+ op1_val &= ~RING_OP1_CR_SW_DEQ_PTR;
+ op1_val |= FIELD_PREP(RING_OP1_CR_SW_DEQ_PTR, done_ptr);
+ rh_reg_write(RING_OPERATION1, op1_val);
+- spin_unlock(&rh->lock);
++ spin_unlock(&hci->lock);
+ }
+
+ static int hci_dma_request_ibi(struct i3c_hci *hci, struct i3c_dev_desc *dev,
+@@ -759,12 +757,12 @@ static void hci_dma_process_ibi(struct i
+
+ done:
+ /* take care to update the ibi dequeue pointer atomically */
+- spin_lock(&rh->lock);
++ spin_lock(&hci->lock);
+ op1_val = rh_reg_read(RING_OPERATION1);
+ op1_val &= ~RING_OP1_IBI_DEQ_PTR;
+ op1_val |= FIELD_PREP(RING_OP1_IBI_DEQ_PTR, deq_ptr);
+ rh_reg_write(RING_OPERATION1, op1_val);
+- spin_unlock(&rh->lock);
++ spin_unlock(&hci->lock);
+
+ /* update the chunk pointer */
+ rh->ibi_chunk_ptr += ibi_chunks;
+--- a/drivers/i3c/master/mipi-i3c-hci/hci.h
++++ b/drivers/i3c/master/mipi-i3c-hci/hci.h
+@@ -45,6 +45,7 @@ struct i3c_hci {
+ const struct hci_io_ops *io;
+ void *io_data;
+ const struct hci_cmd_ops *cmd;
++ spinlock_t lock;
+ atomic_t next_cmd_tid;
+ u32 caps;
+ unsigned int quirks;
+--- a/drivers/i3c/master/mipi-i3c-hci/pio.c
++++ b/drivers/i3c/master/mipi-i3c-hci/pio.c
+@@ -124,7 +124,6 @@ struct hci_pio_ibi_data {
+ };
+
+ struct hci_pio_data {
+- spinlock_t lock;
+ struct hci_xfer *curr_xfer, *xfer_queue;
+ struct hci_xfer *curr_rx, *rx_queue;
+ struct hci_xfer *curr_tx, *tx_queue;
+@@ -146,7 +145,6 @@ static int hci_pio_init(struct i3c_hci *
+ return -ENOMEM;
+
+ hci->io_data = pio;
+- spin_lock_init(&pio->lock);
+
+ size_val = pio_reg_read(QUEUE_SIZE);
+ dev_info(&hci->master.dev, "CMD/RESP FIFO = %ld entries\n",
+@@ -609,7 +607,7 @@ static int hci_pio_queue_xfer(struct i3c
+ xfer[i].data_left = xfer[i].data_len;
+ }
+
+- spin_lock_irq(&pio->lock);
++ spin_lock_irq(&hci->lock);
+ prev_queue_tail = pio->xfer_queue;
+ pio->xfer_queue = &xfer[n - 1];
+ if (pio->curr_xfer) {
+@@ -623,7 +621,7 @@ static int hci_pio_queue_xfer(struct i3c
+ pio_reg_read(INTR_STATUS),
+ pio_reg_read(INTR_SIGNAL_ENABLE));
+ }
+- spin_unlock_irq(&pio->lock);
++ spin_unlock_irq(&hci->lock);
+ return 0;
+ }
+
+@@ -694,14 +692,14 @@ static bool hci_pio_dequeue_xfer(struct
+ struct hci_pio_data *pio = hci->io_data;
+ int ret;
+
+- spin_lock_irq(&pio->lock);
++ spin_lock_irq(&hci->lock);
+ dev_dbg(&hci->master.dev, "n=%d status=%#x/%#x", n,
+ pio_reg_read(INTR_STATUS), pio_reg_read(INTR_SIGNAL_ENABLE));
+ dev_dbg(&hci->master.dev, "main_status = %#x/%#x",
+ readl(hci->base_regs + 0x20), readl(hci->base_regs + 0x28));
+
+ ret = hci_pio_dequeue_xfer_common(hci, pio, xfer, n);
+- spin_unlock_irq(&pio->lock);
++ spin_unlock_irq(&hci->lock);
+ return ret;
+ }
+
+@@ -994,13 +992,13 @@ static bool hci_pio_irq_handler(struct i
+ struct hci_pio_data *pio = hci->io_data;
+ u32 status;
+
+- spin_lock(&pio->lock);
++ spin_lock(&hci->lock);
+ status = pio_reg_read(INTR_STATUS);
+ dev_dbg(&hci->master.dev, "PIO_INTR_STATUS %#x/%#x",
+ status, pio->enabled_irqs);
+ status &= pio->enabled_irqs | STAT_LATENCY_WARNINGS;
+ if (!status) {
+- spin_unlock(&pio->lock);
++ spin_unlock(&hci->lock);
+ return false;
+ }
+
+@@ -1036,7 +1034,7 @@ static bool hci_pio_irq_handler(struct i
+ pio_reg_write(INTR_SIGNAL_ENABLE, pio->enabled_irqs);
+ dev_dbg(&hci->master.dev, "PIO_INTR_STATUS %#x/%#x",
+ pio_reg_read(INTR_STATUS), pio_reg_read(INTR_SIGNAL_ENABLE));
+- spin_unlock(&pio->lock);
++ spin_unlock(&hci->lock);
+ return true;
+ }
+
--- /dev/null
+From b795e68bf3073d67bebbb5a44d93f49efc5b8cc7 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 6 Mar 2026 09:24:45 +0200
+Subject: i3c: mipi-i3c-hci: Correct RING_CTRL_ABORT handling in DMA dequeue
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit b795e68bf3073d67bebbb5a44d93f49efc5b8cc7 upstream.
+
+The logic used to abort the DMA ring contains several flaws:
+
+ 1. The driver unconditionally issues a ring abort even when the ring has
+ already stopped.
+ 2. The completion used to wait for abort completion is never
+ re-initialized, resulting in incorrect wait behavior.
+ 3. The abort sequence unintentionally clears RING_CTRL_ENABLE, which
+ resets hardware ring pointers and disrupts the controller state.
+ 4. If the ring is already stopped, the abort operation should be
+ considered successful without attempting further action.
+
+Fix the abort handling by checking whether the ring is running before
+issuing an abort, re-initializing the completion when needed, ensuring that
+RING_CTRL_ENABLE remains asserted during abort, and treating an already
+stopped ring as a successful condition.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-9-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -485,18 +485,25 @@ static bool hci_dma_dequeue_xfer(struct
+ struct hci_rh_data *rh = &rings->headers[xfer_list[0].ring_number];
+ unsigned int i;
+ bool did_unqueue = false;
++ u32 ring_status;
+
+ guard(mutex)(&hci->control_mutex);
+
+- /* stop the ring */
+- rh_reg_write(RING_CONTROL, RING_CTRL_ABORT);
+- if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) {
+- /*
+- * We're deep in it if ever this condition is ever met.
+- * Hardware might still be writing to memory, etc.
+- */
+- dev_crit(&hci->master.dev, "unable to abort the ring\n");
+- WARN_ON(1);
++ ring_status = rh_reg_read(RING_STATUS);
++ if (ring_status & RING_STATUS_RUNNING) {
++ /* stop the ring */
++ reinit_completion(&rh->op_done);
++ rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_ABORT);
++ wait_for_completion_timeout(&rh->op_done, HZ);
++ ring_status = rh_reg_read(RING_STATUS);
++ if (ring_status & RING_STATUS_RUNNING) {
++ /*
++ * We're deep in it if ever this condition is ever met.
++ * Hardware might still be writing to memory, etc.
++ */
++ dev_crit(&hci->master.dev, "unable to abort the ring\n");
++ WARN_ON(1);
++ }
+ }
+
+ for (i = 0; i < n; i++) {
--- /dev/null
+From f3bcbfe1b8b0b836b772927f75f8cb6e759eb00a Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 6 Mar 2026 09:24:40 +0200
+Subject: i3c: mipi-i3c-hci: Factor out DMA mapping from queuing path
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit f3bcbfe1b8b0b836b772927f75f8cb6e759eb00a upstream.
+
+Prepare for fixing a race in the DMA ring enqueue path when handling
+parallel transfers. Move all DMA mapping out of hci_dma_queue_xfer()
+and into a new helper that performs the mapping up front.
+
+This refactoring allows the upcoming fix to extend the spinlock coverage
+around the enqueue operation without performing DMA mapping under the
+spinlock.
+
+No functional change is intended in this patch.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-4-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 49 ++++++++++++++++++++++------------
+ 1 file changed, 33 insertions(+), 16 deletions(-)
+
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -375,6 +375,33 @@ static void hci_dma_unmap_xfer(struct i3
+ }
+ }
+
++static struct i3c_dma *hci_dma_map_xfer(struct device *dev, struct hci_xfer *xfer)
++{
++ enum dma_data_direction dir = xfer->rnw ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
++ bool need_bounce = device_iommu_mapped(dev) && xfer->rnw && (xfer->data_len & 3);
++
++ return i3c_master_dma_map_single(dev, xfer->data, xfer->data_len, need_bounce, dir);
++}
++
++static int hci_dma_map_xfer_list(struct i3c_hci *hci, struct device *dev,
++ struct hci_xfer *xfer_list, int n)
++{
++ for (int i = 0; i < n; i++) {
++ struct hci_xfer *xfer = xfer_list + i;
++
++ if (!xfer->data)
++ continue;
++
++ xfer->dma = hci_dma_map_xfer(dev, xfer);
++ if (!xfer->dma) {
++ hci_dma_unmap_xfer(hci, xfer_list, i);
++ return -ENOMEM;
++ }
++ }
++
++ return 0;
++}
++
+ static int hci_dma_queue_xfer(struct i3c_hci *hci,
+ struct hci_xfer *xfer_list, int n)
+ {
+@@ -382,6 +409,11 @@ static int hci_dma_queue_xfer(struct i3c
+ struct hci_rh_data *rh;
+ unsigned int i, ring, enqueue_ptr;
+ u32 op1_val, op2_val;
++ int ret;
++
++ ret = hci_dma_map_xfer_list(hci, rings->sysdev, xfer_list, n);
++ if (ret)
++ return ret;
+
+ /* For now we only use ring 0 */
+ ring = 0;
+@@ -392,9 +424,6 @@ static int hci_dma_queue_xfer(struct i3c
+ for (i = 0; i < n; i++) {
+ struct hci_xfer *xfer = xfer_list + i;
+ u32 *ring_data = rh->xfer + rh->xfer_struct_sz * enqueue_ptr;
+- enum dma_data_direction dir = xfer->rnw ? DMA_FROM_DEVICE :
+- DMA_TO_DEVICE;
+- bool need_bounce;
+
+ /* store cmd descriptor */
+ *ring_data++ = xfer->cmd_desc[0];
+@@ -413,18 +442,6 @@ static int hci_dma_queue_xfer(struct i3c
+
+ /* 2nd and 3rd words of Data Buffer Descriptor Structure */
+ if (xfer->data) {
+- need_bounce = device_iommu_mapped(rings->sysdev) &&
+- xfer->rnw &&
+- xfer->data_len != ALIGN(xfer->data_len, 4);
+- xfer->dma = i3c_master_dma_map_single(rings->sysdev,
+- xfer->data,
+- xfer->data_len,
+- need_bounce,
+- dir);
+- if (!xfer->dma) {
+- hci_dma_unmap_xfer(hci, xfer_list, i);
+- return -ENOMEM;
+- }
+ *ring_data++ = lower_32_bits(xfer->dma->addr);
+ *ring_data++ = upper_32_bits(xfer->dma->addr);
+ } else {
+@@ -447,7 +464,7 @@ static int hci_dma_queue_xfer(struct i3c
+ op2_val = rh_reg_read(RING_OPERATION2);
+ if (enqueue_ptr == FIELD_GET(RING_OP2_CR_DEQ_PTR, op2_val)) {
+ /* the ring is full */
+- hci_dma_unmap_xfer(hci, xfer_list, i + 1);
++ hci_dma_unmap_xfer(hci, xfer_list, n);
+ return -EBUSY;
+ }
+ }
--- /dev/null
+From 1dca8aee80eea76d2aae21265de5dd64f6ba0f09 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 6 Mar 2026 09:24:43 +0200
+Subject: i3c: mipi-i3c-hci: Fix race in DMA ring dequeue
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 1dca8aee80eea76d2aae21265de5dd64f6ba0f09 upstream.
+
+The HCI DMA dequeue path (hci_dma_dequeue_xfer()) may be invoked for
+multiple transfers that timeout around the same time. However, the
+function is not serialized and can race with itself.
+
+When a timeout occurs, hci_dma_dequeue_xfer() stops the ring, processes
+incomplete transfers, and then restarts the ring. If another timeout
+triggers a parallel call into the same function, the two instances may
+interfere with each other - stopping or restarting the ring at unexpected
+times.
+
+Add a mutex so that hci_dma_dequeue_xfer() is serialized with respect to
+itself.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-7-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/core.c | 1 +
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 2 ++
+ drivers/i3c/master/mipi-i3c-hci/hci.h | 1 +
+ 3 files changed, 4 insertions(+)
+
+--- a/drivers/i3c/master/mipi-i3c-hci/core.c
++++ b/drivers/i3c/master/mipi-i3c-hci/core.c
+@@ -632,6 +632,7 @@ static int i3c_hci_init(struct i3c_hci *
+ return ret;
+
+ spin_lock_init(&hci->lock);
++ mutex_init(&hci->control_mutex);
+
+ /*
+ * Now let's reset the hardware.
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -486,6 +486,8 @@ static bool hci_dma_dequeue_xfer(struct
+ unsigned int i;
+ bool did_unqueue = false;
+
++ guard(mutex)(&hci->control_mutex);
++
+ /* stop the ring */
+ rh_reg_write(RING_CONTROL, RING_CTRL_ABORT);
+ if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) {
+--- a/drivers/i3c/master/mipi-i3c-hci/hci.h
++++ b/drivers/i3c/master/mipi-i3c-hci/hci.h
+@@ -46,6 +46,7 @@ struct i3c_hci {
+ void *io_data;
+ const struct hci_cmd_ops *cmd;
+ spinlock_t lock;
++ struct mutex control_mutex;
+ atomic_t next_cmd_tid;
+ u32 caps;
+ unsigned int quirks;
--- /dev/null
+From b6d586431ae20d5157ee468d0ef62ad26798ef13 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 6 Mar 2026 09:24:47 +0200
+Subject: i3c: mipi-i3c-hci: Restart DMA ring correctly after dequeue abort
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit b6d586431ae20d5157ee468d0ef62ad26798ef13 upstream.
+
+The DMA dequeue path attempts to restart the ring after aborting an
+in-flight transfer, but the current sequence is incomplete. The controller
+must be brought out of the aborted state and the ring control registers
+must be programmed in the correct order: first clearing ABORT, then
+re-enabling the ring and asserting RUN_STOP to resume operation.
+
+Add the missing controller resume step and update the ring control writes
+so that the ring is restarted using the proper sequence.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-11-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -528,7 +528,9 @@ static bool hci_dma_dequeue_xfer(struct
+ }
+
+ /* restart the ring */
++ mipi_i3c_hci_resume(hci);
+ rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE);
++ rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_RUN_STOP);
+
+ return did_unqueue;
+ }
--- /dev/null
+From 4167b8914463132654e01e16259847d097f8a7f7 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 6 Mar 2026 09:24:38 +0200
+Subject: i3c: mipi-i3c-hci: Use ETIMEDOUT instead of ETIME for timeout errors
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 4167b8914463132654e01e16259847d097f8a7f7 upstream.
+
+The MIPI I3C HCI driver currently returns -ETIME for various timeout
+conditions, while other I3C master drivers consistently use -ETIMEDOUT
+for the same class of errors. Align the HCI driver with the rest of the
+subsystem by replacing all uses of -ETIME with -ETIMEDOUT.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-2-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/cmd_v1.c | 2 +-
+ drivers/i3c/master/mipi-i3c-hci/cmd_v2.c | 2 +-
+ drivers/i3c/master/mipi-i3c-hci/core.c | 6 +++---
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/i3c/master/mipi-i3c-hci/cmd_v1.c
++++ b/drivers/i3c/master/mipi-i3c-hci/cmd_v1.c
+@@ -336,7 +336,7 @@ static int hci_cmd_v1_daa(struct i3c_hci
+ hci->io->queue_xfer(hci, xfer, 1);
+ if (!wait_for_completion_timeout(&done, HZ) &&
+ hci->io->dequeue_xfer(hci, xfer, 1)) {
+- ret = -ETIME;
++ ret = -ETIMEDOUT;
+ break;
+ }
+ if ((RESP_STATUS(xfer->response) == RESP_ERR_ADDR_HEADER ||
+--- a/drivers/i3c/master/mipi-i3c-hci/cmd_v2.c
++++ b/drivers/i3c/master/mipi-i3c-hci/cmd_v2.c
+@@ -277,7 +277,7 @@ static int hci_cmd_v2_daa(struct i3c_hci
+ hci->io->queue_xfer(hci, xfer, 2);
+ if (!wait_for_completion_timeout(&done, HZ) &&
+ hci->io->dequeue_xfer(hci, xfer, 2)) {
+- ret = -ETIME;
++ ret = -ETIMEDOUT;
+ break;
+ }
+ if (RESP_STATUS(xfer[0].response) != RESP_SUCCESS) {
+--- a/drivers/i3c/master/mipi-i3c-hci/core.c
++++ b/drivers/i3c/master/mipi-i3c-hci/core.c
+@@ -230,7 +230,7 @@ static int i3c_hci_send_ccc_cmd(struct i
+ goto out;
+ if (!wait_for_completion_timeout(&done, HZ) &&
+ hci->io->dequeue_xfer(hci, xfer, nxfers)) {
+- ret = -ETIME;
++ ret = -ETIMEDOUT;
+ goto out;
+ }
+ for (i = prefixed; i < nxfers; i++) {
+@@ -309,7 +309,7 @@ static int i3c_hci_priv_xfers(struct i3c
+ goto out;
+ if (!wait_for_completion_timeout(&done, HZ) &&
+ hci->io->dequeue_xfer(hci, xfer, nxfers)) {
+- ret = -ETIME;
++ ret = -ETIMEDOUT;
+ goto out;
+ }
+ for (i = 0; i < nxfers; i++) {
+@@ -357,7 +357,7 @@ static int i3c_hci_i2c_xfers(struct i2c_
+ goto out;
+ if (!wait_for_completion_timeout(&done, m->i2c.timeout) &&
+ hci->io->dequeue_xfer(hci, xfer, nxfers)) {
+- ret = -ETIME;
++ ret = -ETIMEDOUT;
+ goto out;
+ }
+ for (i = 0; i < nxfers; i++) {
iio-imu-inv_icm42600-fix-odr-switch-when-turning-buffer-off.patch
iio-proximity-hx9023s-fix-assignment-order-for-__counted_by.patch
iio-proximity-hx9023s-protect-against-division-by-zero-in-set_samp_freq.patch
+i3c-mipi-i3c-hci-use-etimedout-instead-of-etime-for-timeout-errors.patch
+i3c-mipi-i3c-hci-factor-out-dma-mapping-from-queuing-path.patch
+i3c-mipi-i3c-hci-consolidate-spinlocks.patch
+i3c-mipi-i3c-hci-restart-dma-ring-correctly-after-dequeue-abort.patch
+i3c-mipi-i3c-hci-add-missing-tid-field-to-no-op-command-descriptor.patch
+i3c-mipi-i3c-hci-fix-race-in-dma-ring-dequeue.patch
+i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in-dma-dequeue.patch