[PATCH 15/16] i3c: mipi-i3c-hci: Consolidate DMA ring allocation
From: Adrian Hunter
Date: Thu Apr 16 2026 - 14:05:46 EST
dma_alloc_coherent() allocates memory in whole pages, which can waste
space when command and response queues are allocated separately.
Allocate the DMA command and response queues from a single coherent
allocation instead, while preserving the required 4-byte alignment.
This reduces memory overhead without changing behavior.
Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
---
drivers/i3c/master/mipi-i3c-hci/dma.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
index 527c282e0734..b06405a9aa7b 100644
--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
+++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
@@ -186,14 +186,12 @@ static void hci_dma_free(void *data)
for (int i = 0; i < rings->total; i++) {
rh = &rings->headers[i];
- if (rh->xfer)
- dma_free_coherent(rings->sysdev,
- rh->xfer_struct_sz * rh->xfer_entries,
- rh->xfer, rh->xfer_dma);
- if (rh->resp)
- dma_free_coherent(rings->sysdev,
- rh->resp_struct_sz * rh->xfer_entries,
- rh->resp, rh->resp_dma);
+ if (rh->xfer) {
+ size_t sz = round_up(rh->xfer_struct_sz * rh->xfer_entries, 4);
+
+ sz += rh->resp_struct_sz * rh->xfer_entries;
+ dma_free_coherent(rings->sysdev, sz, rh->xfer, rh->xfer_dma);
+ }
kfree(rh->src_xfers);
if (rh->ibi_status)
dma_free_coherent(rings->sysdev,
@@ -359,17 +357,17 @@ static int hci_dma_init(struct i3c_hci *hci)
dev_dbg(&hci->master.dev,
"xfer_struct_sz = %d, resp_struct_sz = %d",
rh->xfer_struct_sz, rh->resp_struct_sz);
- xfers_sz = rh->xfer_struct_sz * rh->xfer_entries;
+ xfers_sz = round_up(rh->xfer_struct_sz * rh->xfer_entries, 4);
resps_sz = rh->resp_struct_sz * rh->xfer_entries;
- rh->xfer = dma_alloc_coherent(rings->sysdev, xfers_sz,
+ rh->xfer = dma_alloc_coherent(rings->sysdev, xfers_sz + resps_sz,
&rh->xfer_dma, GFP_KERNEL);
- rh->resp = dma_alloc_coherent(rings->sysdev, resps_sz,
- &rh->resp_dma, GFP_KERNEL);
+ rh->resp = rh->xfer + xfers_sz;
+ rh->resp_dma = rh->xfer_dma + xfers_sz;
rh->src_xfers =
kzalloc_objs(*rh->src_xfers, rh->xfer_entries);
ret = -ENOMEM;
- if (!rh->xfer || !rh->resp || !rh->src_xfers)
+ if (!rh->xfer || !rh->src_xfers)
goto err_out;
/* IBIs */
--
2.51.0