Skip to content

Commit d6e90df

Browse files
ahunter6gregkh
authored andcommitted
i3c: mipi-i3c-hci: Consolidate spinlocks
commit fa12bb9 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: 9ad9a52 ("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>
1 parent 909ce72 commit d6e90df

4 files changed

Lines changed: 16 additions & 17 deletions

File tree

drivers/i3c/master/mipi-i3c-hci/core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ static int i3c_hci_init(struct i3c_hci *hci)
631631
if (ret)
632632
return ret;
633633

634+
spin_lock_init(&hci->lock);
635+
634636
/*
635637
* Now let's reset the hardware.
636638
* SOFT_RST must be clear before we write to it.

drivers/i3c/master/mipi-i3c-hci/dma.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ struct hci_rh_data {
133133
unsigned int xfer_struct_sz, resp_struct_sz, ibi_status_sz, ibi_chunk_sz;
134134
unsigned int done_ptr, ibi_chunk_ptr;
135135
struct hci_xfer **src_xfers;
136-
spinlock_t lock;
137136
struct completion op_done;
138137
};
139138

@@ -240,7 +239,6 @@ static int hci_dma_init(struct i3c_hci *hci)
240239
goto err_out;
241240
rh = &rings->headers[i];
242241
rh->regs = hci->base_regs + offset;
243-
spin_lock_init(&rh->lock);
244242
init_completion(&rh->op_done);
245243

246244
rh->xfer_entries = XFER_RING_ENTRIES;
@@ -470,12 +468,12 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci,
470468
}
471469

472470
/* take care to update the hardware enqueue pointer atomically */
473-
spin_lock_irq(&rh->lock);
471+
spin_lock_irq(&hci->lock);
474472
op1_val = rh_reg_read(RING_OPERATION1);
475473
op1_val &= ~RING_OP1_CR_ENQ_PTR;
476474
op1_val |= FIELD_PREP(RING_OP1_CR_ENQ_PTR, enqueue_ptr);
477475
rh_reg_write(RING_OPERATION1, op1_val);
478-
spin_unlock_irq(&rh->lock);
476+
spin_unlock_irq(&hci->lock);
479477

480478
return 0;
481479
}
@@ -573,12 +571,12 @@ static void hci_dma_xfer_done(struct i3c_hci *hci, struct hci_rh_data *rh)
573571
}
574572

575573
/* take care to update the software dequeue pointer atomically */
576-
spin_lock(&rh->lock);
574+
spin_lock(&hci->lock);
577575
op1_val = rh_reg_read(RING_OPERATION1);
578576
op1_val &= ~RING_OP1_CR_SW_DEQ_PTR;
579577
op1_val |= FIELD_PREP(RING_OP1_CR_SW_DEQ_PTR, done_ptr);
580578
rh_reg_write(RING_OPERATION1, op1_val);
581-
spin_unlock(&rh->lock);
579+
spin_unlock(&hci->lock);
582580
}
583581

584582
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 i3c_hci *hci, struct hci_rh_data *rh)
759757

760758
done:
761759
/* take care to update the ibi dequeue pointer atomically */
762-
spin_lock(&rh->lock);
760+
spin_lock(&hci->lock);
763761
op1_val = rh_reg_read(RING_OPERATION1);
764762
op1_val &= ~RING_OP1_IBI_DEQ_PTR;
765763
op1_val |= FIELD_PREP(RING_OP1_IBI_DEQ_PTR, deq_ptr);
766764
rh_reg_write(RING_OPERATION1, op1_val);
767-
spin_unlock(&rh->lock);
765+
spin_unlock(&hci->lock);
768766

769767
/* update the chunk pointer */
770768
rh->ibi_chunk_ptr += ibi_chunks;

drivers/i3c/master/mipi-i3c-hci/hci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct i3c_hci {
4545
const struct hci_io_ops *io;
4646
void *io_data;
4747
const struct hci_cmd_ops *cmd;
48+
spinlock_t lock;
4849
atomic_t next_cmd_tid;
4950
u32 caps;
5051
unsigned int quirks;

drivers/i3c/master/mipi-i3c-hci/pio.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ struct hci_pio_ibi_data {
124124
};
125125

126126
struct hci_pio_data {
127-
spinlock_t lock;
128127
struct hci_xfer *curr_xfer, *xfer_queue;
129128
struct hci_xfer *curr_rx, *rx_queue;
130129
struct hci_xfer *curr_tx, *tx_queue;
@@ -146,7 +145,6 @@ static int hci_pio_init(struct i3c_hci *hci)
146145
return -ENOMEM;
147146

148147
hci->io_data = pio;
149-
spin_lock_init(&pio->lock);
150148

151149
size_val = pio_reg_read(QUEUE_SIZE);
152150
dev_info(&hci->master.dev, "CMD/RESP FIFO = %ld entries\n",
@@ -609,7 +607,7 @@ static int hci_pio_queue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n)
609607
xfer[i].data_left = xfer[i].data_len;
610608
}
611609

612-
spin_lock_irq(&pio->lock);
610+
spin_lock_irq(&hci->lock);
613611
prev_queue_tail = pio->xfer_queue;
614612
pio->xfer_queue = &xfer[n - 1];
615613
if (pio->curr_xfer) {
@@ -623,7 +621,7 @@ static int hci_pio_queue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n)
623621
pio_reg_read(INTR_STATUS),
624622
pio_reg_read(INTR_SIGNAL_ENABLE));
625623
}
626-
spin_unlock_irq(&pio->lock);
624+
spin_unlock_irq(&hci->lock);
627625
return 0;
628626
}
629627

@@ -694,14 +692,14 @@ static bool hci_pio_dequeue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int
694692
struct hci_pio_data *pio = hci->io_data;
695693
int ret;
696694

697-
spin_lock_irq(&pio->lock);
695+
spin_lock_irq(&hci->lock);
698696
dev_dbg(&hci->master.dev, "n=%d status=%#x/%#x", n,
699697
pio_reg_read(INTR_STATUS), pio_reg_read(INTR_SIGNAL_ENABLE));
700698
dev_dbg(&hci->master.dev, "main_status = %#x/%#x",
701699
readl(hci->base_regs + 0x20), readl(hci->base_regs + 0x28));
702700

703701
ret = hci_pio_dequeue_xfer_common(hci, pio, xfer, n);
704-
spin_unlock_irq(&pio->lock);
702+
spin_unlock_irq(&hci->lock);
705703
return ret;
706704
}
707705

@@ -994,13 +992,13 @@ static bool hci_pio_irq_handler(struct i3c_hci *hci)
994992
struct hci_pio_data *pio = hci->io_data;
995993
u32 status;
996994

997-
spin_lock(&pio->lock);
995+
spin_lock(&hci->lock);
998996
status = pio_reg_read(INTR_STATUS);
999997
dev_dbg(&hci->master.dev, "PIO_INTR_STATUS %#x/%#x",
1000998
status, pio->enabled_irqs);
1001999
status &= pio->enabled_irqs | STAT_LATENCY_WARNINGS;
10021000
if (!status) {
1003-
spin_unlock(&pio->lock);
1001+
spin_unlock(&hci->lock);
10041002
return false;
10051003
}
10061004

@@ -1036,7 +1034,7 @@ static bool hci_pio_irq_handler(struct i3c_hci *hci)
10361034
pio_reg_write(INTR_SIGNAL_ENABLE, pio->enabled_irqs);
10371035
dev_dbg(&hci->master.dev, "PIO_INTR_STATUS %#x/%#x",
10381036
pio_reg_read(INTR_STATUS), pio_reg_read(INTR_SIGNAL_ENABLE));
1039-
spin_unlock(&pio->lock);
1037+
spin_unlock(&hci->lock);
10401038
return true;
10411039
}
10421040

0 commit comments

Comments
 (0)