git: 2088e5bdac39 - stable/13 - LinuxKPI: dma-mapping: add dmam_alloc_coherent()

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Mon, 17 Oct 2022 20:41:39 UTC
The branch stable/13 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=2088e5bdac398e5f084739fd4f4d206530178c33

commit 2088e5bdac398e5f084739fd4f4d206530178c33
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-09-21 20:58:05 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-10-17 20:37:04 +0000

    LinuxKPI: dma-mapping: add dmam_alloc_coherent()
    
    Add the devres version dmam_alloc_coherent() of dma_alloc_coherent()
    along with the ancillary free function.
    
    Sponsored by:   The FreeBSD Foundation
    Reviewed by:    hselasky
    Differential Revision: https://reviews.freebsd.org/D36661
    
    (cherry picked from commit 7105f0d967530852b907375687575a8c2ba62fd2)
---
 .../linuxkpi/common/include/linux/dma-mapping.h    | 10 ++++++
 sys/compat/linuxkpi/common/src/linux_pci.c         | 39 ++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
index 94adb0c64431..ef3570ef7639 100644
--- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
+++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h
@@ -95,6 +95,8 @@ int linux_dma_tag_init(struct device *, u64);
 int linux_dma_tag_init_coherent(struct device *, u64);
 void *linux_dma_alloc_coherent(struct device *dev, size_t size,
     dma_addr_t *dma_handle, gfp_t flag);
+void *linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size,
+    dma_addr_t *dma_handle, gfp_t flag);
 dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len);
 void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t size);
 int linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
@@ -159,6 +161,14 @@ dma_zalloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
 	return (dma_alloc_coherent(dev, size, dma_handle, flag | __GFP_ZERO));
 }
 
+static inline void *
+dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+    gfp_t flag)
+{
+
+	return (linuxkpi_dmam_alloc_coherent(dev, size, dma_handle, flag));
+}
+
 static inline void
 dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
     dma_addr_t dma_addr)
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index f5de87947c37..b0820c9b2c3e 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -1140,6 +1140,45 @@ linux_dma_alloc_coherent(struct device *dev, size_t size,
 	return (mem);
 }
 
+struct lkpi_devres_dmam_coherent {
+	size_t size;
+	dma_addr_t *handle;
+	void *mem;
+};
+
+static void
+lkpi_dmam_free_coherent(struct device *dev, void *p)
+{
+	struct lkpi_devres_dmam_coherent *dr;
+
+	dr = p;
+	dma_free_coherent(dev, dr->size, dr->mem, *dr->handle);
+}
+
+void *
+linuxkpi_dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+    gfp_t flag)
+{
+	struct lkpi_devres_dmam_coherent *dr;
+
+	dr = lkpi_devres_alloc(lkpi_dmam_free_coherent,
+	   sizeof(*dr), GFP_KERNEL | __GFP_ZERO);
+
+	if (dr == NULL)
+		return (NULL);
+
+	dr->size = size;
+	dr->mem = linux_dma_alloc_coherent(dev, size, dma_handle, flag);
+	dr->handle = dma_handle;
+	if (dr->mem == NULL) {
+		lkpi_devres_free(dr);
+		return (NULL);
+	}
+
+	lkpi_devres_add(dev, dr);
+	return (dr->mem);
+}
+
 void
 linuxkpi_dma_sync(struct device *dev, dma_addr_t dma_addr, size_t size,
     bus_dmasync_op_t op)