From 438e8d8294b1f08e4c9596a2bec2ee650f9f4401 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 12 May 2005 10:25:58 +0200 Subject: [PATCH] --- yaml --- r: 1557 b: refs/heads/master c: 9b9a5afffd8636a82c6b32970342aef9d1f3d17d h: refs/heads/master i: 1555: 89941a44631fda7730f405229f8ee9e1bd38b6c6 v: v3 --- [refs] | 2 +- trunk/sound/arm/devdma.c | 81 ++++++++++++++++++++++++++++++++++++++++ trunk/sound/arm/devdma.h | 3 ++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 trunk/sound/arm/devdma.c create mode 100644 trunk/sound/arm/devdma.h diff --git a/[refs] b/[refs] index a8be078a3fac..686223776a9b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f7de9cfd25b6867a2854d98d734e03e1a9fc65fb +refs/heads/master: 9b9a5afffd8636a82c6b32970342aef9d1f3d17d diff --git a/trunk/sound/arm/devdma.c b/trunk/sound/arm/devdma.c new file mode 100644 index 000000000000..60826a5324b4 --- /dev/null +++ b/trunk/sound/arm/devdma.c @@ -0,0 +1,81 @@ +/* + * linux/sound/arm/devdma.c + * + * Copyright (C) 2003-2004 Russell King, All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ARM DMA shim for ALSA. + */ +#include +#include + +#include +#include +#include + +#include "devdma.h" + +void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream) +{ + snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_dma_buffer *buf = runtime->dma_buffer_p; + + if (runtime->dma_area == NULL) + return; + + if (buf != &substream->dma_buffer) { + dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr); + kfree(runtime->dma_buffer_p); + } + + snd_pcm_set_runtime_buffer(substream, NULL); +} + +int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size) +{ + snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_dma_buffer *buf = runtime->dma_buffer_p; + int ret = 0; + + if (buf) { + if (buf->bytes >= size) + goto out; + devdma_hw_free(dev, substream); + } + + if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) { + buf = &substream->dma_buffer; + } else { + buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL); + if (!buf) + goto nomem; + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = dev; + buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL); + buf->bytes = size; + buf->private_data = NULL; + + if (!buf->area) + goto free; + } + snd_pcm_set_runtime_buffer(substream, buf); + ret = 1; + out: + runtime->dma_bytes = size; + return ret; + + free: + kfree(buf); + nomem: + return -ENOMEM; +} + +int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma) +{ + snd_pcm_runtime_t *runtime = substream->runtime; + return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); +} diff --git a/trunk/sound/arm/devdma.h b/trunk/sound/arm/devdma.h new file mode 100644 index 000000000000..5a33b6bacc34 --- /dev/null +++ b/trunk/sound/arm/devdma.h @@ -0,0 +1,3 @@ +void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream); +int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size); +int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma);