[PATCH master 15/23] firmware: qemu_fw_cfg: use bounce buffer for write
Ahmad Fatoum
a.fatoum at pengutronix.de
Tue Apr 23 23:40:50 PDT 2024
qemu_fw_cfg seems to be the only cdev that expect DMA-aligned memory in
its write operation. We don't generally allocate buffers for read() with
dma_alloc though, so introduce a bounce buffer. The write callback is
only used once for initial configuration of the frame buffer device, so
the allocation won't be noticeable.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
drivers/firmware/qemu_fw_cfg.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 1ba81d1b5002..3f129a2c1e02 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -173,14 +173,24 @@ static ssize_t fw_cfg_write(struct cdev *cdev, const void *buf, size_t count,
struct fw_cfg *fw_cfg = to_fw_cfg(cdev);
struct device *dev = cdev->dev;
struct fw_cfg_dma __iomem *acc = fw_cfg->acc_virt;
+ void *dma_buf;
dma_addr_t mapping;
+ int ret = 0;
if (pos != 0)
return -EINVAL;
- mapping = dma_map_single(dev, (void *)buf, count, DMA_TO_DEVICE);
- if (dma_mapping_error(dev, mapping))
- return -EFAULT;
+ dma_buf = dma_alloc(count);
+ if (!dma_buf)
+ return -ENOMEM;
+
+ memcpy(dma_buf, buf, count);
+
+ mapping = dma_map_single(dev, dma_buf, count, DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, mapping)) {
+ ret = -EFAULT;
+ goto free_buf;
+ }
fw_cfg->next_read_offset = 0;
@@ -195,8 +205,10 @@ static ssize_t fw_cfg_write(struct cdev *cdev, const void *buf, size_t count,
;
dma_unmap_single(dev, mapping, count, DMA_FROM_DEVICE);
+free_buf:
+ dma_free(dma_buf);
- return count;
+ return ret ?: count;
}
static struct cdev_operations fw_cfg_ops = {
--
2.39.2
More information about the barebox
mailing list