[PATCH v2 5/5] bus: mhi: ep: Use batched read for ring caching
Sumit Kumar <[email protected]> Mon, 03 Aug 2026 16:01:47 +0530
| Newsgroups | org.kernel.vger.dmaengine,dev.linux.lists.mhi,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
Optimise ring caching in __mhi_ep_cache_ring(). For the non-wraparound case, use read_sync(); for the wraparound case where ring data spans two non-contiguous host memory regions, both the tail portion (start -> ring_size) and head portion (0 -> end) are submitted using the new read_batch() API in a single operation. On DMA-capable platforms this transfers both segments in one DMA transaction. Signed-off-by: Sumit Kumar <[email protected]> --- drivers/bus/mhi/ep/ring.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c index 405ce16c02a89ea2268ea1033ff5c1c26b1c81bd..a369c1eb0c0b849d7ced01b99898ca461cf680b9 100644 --- a/drivers/bus/mhi/ep/ring.c +++ b/drivers/bus/mhi/ep/ring.c @@ -30,7 +30,6 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) { struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; struct device *dev = &mhi_cntrl->mhi_dev->dev; - struct mhi_ep_buf_info buf_info = {}; size_t start; int ret; @@ -44,6 +43,8 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) start = ring->wr_offset; if (start < end) { + struct mhi_ep_buf_info buf_info = {}; + buf_info.size = (end - start) * sizeof(struct mhi_ring_element); buf_info.host_addr = ring->rbase + (start * sizeof(struct mhi_ring_element)); buf_info.dev_addr = &ring->ring_cache[start]; @@ -51,27 +52,30 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info); if (ret) return ret; + + dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, + buf_info.size); } else { - buf_info.size = (ring->ring_size - start) * sizeof(struct mhi_ring_element); - buf_info.host_addr = ring->rbase + (start * sizeof(struct mhi_ring_element)); - buf_info.dev_addr = &ring->ring_cache[start]; + struct mhi_ep_buf_info buf_info[2] = {}; + u32 count = 1; - ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info); - if (ret) - return ret; + buf_info[0].size = (ring->ring_size - start) * sizeof(struct mhi_ring_element); + buf_info[0].host_addr = ring->rbase + (start * sizeof(struct mhi_ring_element)); + buf_info[0].dev_addr = &ring->ring_cache[start]; if (end) { - buf_info.host_addr = ring->rbase; - buf_info.dev_addr = &ring->ring_cache[0]; - buf_info.size = end * sizeof(struct mhi_ring_element); - - ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info); - if (ret) - return ret; + buf_info[1].size = end * sizeof(struct mhi_ring_element); + buf_info[1].host_addr = ring->rbase; + buf_info[1].dev_addr = &ring->ring_cache[0]; + count = 2; } - } + ret = mhi_cntrl->read_batch(mhi_cntrl, buf_info, count); + if (ret) + return ret; - dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, buf_info.size); + dev_dbg(dev, "Cached ring (batched): start %zu end %zu tail_size %zu head_size %zu count %u\n", + start, end, buf_info[0].size, end ? buf_info[1].size : 0, count); + } return 0; } -- 2.34.1