[PATCH RFC v2 4/4] ALSA: memalloc: Support for non-coherent page allocation
Takashi Iwai
tiwai at suse.de
Thu Aug 12 13:38:18 CEST 2021
This patch adds the new non-coherent contiguous page allocation to the
standard memalloc helper. Like the previous patch to add the
non-contig SG-buffer support, this non-coherent type is also direction
and requires the explicit sync, too. Hence the driver using this type
of buffer would have to set SNDRV_PCM_INFO_EXPLICIT_SYNC flag to the
PCM hardware.info as well.
Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
include/sound/memalloc.h | 1 +
sound/core/memalloc.c | 43 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index 30284985c8e9..0bea11c7a3b1 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -49,6 +49,7 @@ struct snd_dma_device {
#endif
#define SNDRV_DMA_TYPE_VMALLOC 7 /* vmalloc'ed buffer */
#define SNDRV_DMA_TYPE_NONCONTIG 8 /* non-coherent SG buffer */
+#define SNDRV_DMA_TYPE_NONCOHERENT 9 /* non-coherent buffer */
/*
* info for buffer allocation
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index ff8d5d59c9e7..5a7d2bffa7b9 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -552,6 +552,48 @@ static const struct snd_malloc_ops snd_dma_noncontig_ops = {
.get_chunk_size = snd_dma_vmalloc_get_chunk_size,
};
+/*
+ * Non-coherent pages allocator
+ */
+static void *snd_dma_noncoherent_alloc(struct snd_dma_buffer *dmab, size_t size)
+{
+ return dma_alloc_noncoherent(dmab->dev.dev, size, &dmab->addr,
+ dmab->dev.dir, DEFAULT_GFP);
+}
+
+static void snd_dma_noncoherent_free(struct snd_dma_buffer *dmab)
+{
+ dma_free_noncoherent(dmab->dev.dev, dmab->bytes, dmab->area,
+ dmab->addr, dmab->dev.dir);
+}
+
+static int snd_dma_noncoherent_mmap(struct snd_dma_buffer *dmab,
+ struct vm_area_struct *area)
+{
+ area->vm_page_prot = vm_get_page_prot(area->vm_flags);
+ return dma_mmap_pages(dmab->dev.dev, area,
+ area->vm_end - area->vm_start,
+ virt_to_page(dmab->area));
+}
+
+static void snd_dma_noncoherent_sync(struct snd_dma_buffer *dmab,
+ enum snd_dma_sync_mode mode)
+{
+ if (mode == SNDRV_DMA_SYNC_CPU)
+ dma_sync_single_for_cpu(dmab->dev.dev, dmab->addr,
+ dmab->bytes, dmab->dev.dir);
+ else
+ dma_sync_single_for_device(dmab->dev.dev, dmab->addr,
+ dmab->bytes, dmab->dev.dir);
+}
+
+static const struct snd_malloc_ops snd_dma_noncoherent_ops = {
+ .alloc = snd_dma_noncoherent_alloc,
+ .free = snd_dma_noncoherent_free,
+ .mmap = snd_dma_noncoherent_mmap,
+ .sync = snd_dma_noncoherent_sync,
+};
+
#endif /* CONFIG_HAS_DMA */
/*
@@ -564,6 +606,7 @@ static const struct snd_malloc_ops *dma_ops[] = {
[SNDRV_DMA_TYPE_DEV] = &snd_dma_dev_ops,
[SNDRV_DMA_TYPE_DEV_WC] = &snd_dma_wc_ops,
[SNDRV_DMA_TYPE_NONCONTIG] = &snd_dma_noncontig_ops,
+ [SNDRV_DMA_TYPE_NONCOHERENT] = &snd_dma_noncoherent_ops,
#ifdef CONFIG_GENERIC_ALLOCATOR
[SNDRV_DMA_TYPE_DEV_IRAM] = &snd_dma_iram_ops,
#endif /* CONFIG_GENERIC_ALLOCATOR */
--
2.26.2
More information about the Alsa-devel
mailing list