]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
i3c: mipi-i3c-hci: Consolidate DMA ring allocation
authorAdrian Hunter <adrian.hunter@intel.com>
Wed, 3 Jun 2026 09:07:53 +0000 (12:07 +0300)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Sun, 14 Jun 2026 15:21:34 +0000 (17:21 +0200)
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@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260603090754.16252-17-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/i3c/master/mipi-i3c-hci/dma.c

index 9a01c740760f63bece4f468198da90c46df6b746..0136f3064adabb8fe9553388b1ff3adce6a9a133 100644 (file)
@@ -130,7 +130,7 @@ struct hci_rh_data {
        dma_addr_t xfer_dma, resp_dma, ibi_status_dma, ibi_data_dma;
        unsigned int xfer_entries, ibi_status_entries, ibi_chunks_total;
        unsigned int xfer_struct_sz, resp_struct_sz, ibi_status_sz, ibi_chunk_sz;
-       unsigned int done_ptr, ibi_chunk_ptr, xfer_space;
+       unsigned int xfer_alloc_sz, done_ptr, ibi_chunk_ptr, xfer_space;
        struct hci_xfer **src_xfers;
        struct completion op_done;
 };
@@ -187,13 +187,7 @@ static void hci_dma_free(void *data)
                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);
+                       dma_free_coherent(rings->sysdev, rh->xfer_alloc_sz, rh->xfer, rh->xfer_dma);
                kfree(rh->src_xfers);
                if (rh->ibi_status)
                        dma_free_coherent(rings->sysdev,
@@ -359,18 +353,19 @@ 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_alloc_sz = xfers_sz + resps_sz;
 
-               rh->xfer = dma_alloc_coherent(rings->sysdev, xfers_sz,
+               rh->xfer = dma_alloc_coherent(rings->sysdev, rh->xfer_alloc_sz,
                                              &rh->xfer_dma, GFP_KERNEL);
-               rh->resp = dma_alloc_coherent(rings->sysdev, resps_sz,
-                                             &rh->resp_dma, GFP_KERNEL);
                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;
+               rh->resp = rh->xfer + xfers_sz;
+               rh->resp_dma = rh->xfer_dma + xfers_sz;
 
                /* IBIs */