diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h --- 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_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 @@ 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 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -1139,6 +1139,45 @@ 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)