[alsa-devel] [PATCH 0/8] Add and implement gen_pool_dma_alloc()
Previously, we don't have a specific gen_pool_alloc() for DMA usage; Instead, we need to use gen_pool_virt_to_phys() to convert the addr returned from gen_pool_alloc(). So each implementation of this has duplicated code. Thus add new helper function -- gen_pool_dma_alloc().
After gen_pool_dma_alloc() is introduced, we can replace the original combination of gen_pool_alloc()+gen_pool_virt_to_phys() with this new helper function. Thus this patch implement the helper function to all the current drivers which use gen_pool_virt_to_phys().
!!-------------------important------------------!!
The later 7 patches need all related driver owner to test. We can here define a simple rule: 1, If one driver owner or maintainer doesn't like the mofication to his/her driver, just let me know. I would drop that patch. 2, If there's a bug and issue found after patch-testing, please reply the mail so that I can fix and refine the patch. 3, If one driver owner or maintainer is too busy and doesn't have bandwidth to test the patch, I would drop that patch from this series. We can reimplement it till there's someone test it.
!!-------------------current progress-----------!!
lib/genalloc: [Okay] ARM: davinci: [Untested] dma: mmp_tdma: [Untested] [media] coda: [Untested] uio: uio_pruss: [Untested] ALSA: memalloc: [Tested] by Nicolin Chen with i.MX6Q SabreSD ASoC: davinci: [Untested] ASoC: pxa: use [Untested]
Nicolin Chen (8): lib/genalloc: add a helper function for DMA buffer allocation ARM: davinci: use gen_pool_dma_alloc() to sram.c dma: mmp_tdma: use gen_pool_dma_alloc() to allocate descriptor [media] coda: use gen_pool_dma_alloc() to allocate iram buffer uio: uio_pruss: use gen_pool_dma_alloc() to allocate sram memory ALSA: memalloc: use gen_pool_dma_alloc() to allocate iram buffer ASoC: davinci: use gen_pool_dma_alloc() in davinci-pcm.c ASoC: pxa: use gen_pool_dma_alloc() to allocate dma buffer
arch/arm/mach-davinci/sram.c | 9 +-------- drivers/dma/mmp_tdma.c | 7 +------ drivers/media/platform/coda.c | 5 ++--- drivers/uio/uio_pruss.c | 6 ++---- include/linux/genalloc.h | 2 ++ lib/genalloc.c | 28 ++++++++++++++++++++++++++++ sound/core/memalloc.c | 6 +----- sound/soc/davinci/davinci-pcm.c | 3 +-- sound/soc/pxa/mmp-pcm.c | 3 +-- 9 files changed, 39 insertions(+), 30 deletions(-)
When using pool space for DMA buffer, there might be duplicated calling of gen_pool_alloc() and gen_pool_virt_to_phys() in each implementation.
Thus it's better to add a simple helper function, a compatible one to the common dma_alloc_coherent(), to save some code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- include/linux/genalloc.h | 2 ++ lib/genalloc.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+)
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index f8d41cb..1eda33d 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -94,6 +94,8 @@ static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, } extern void gen_pool_destroy(struct gen_pool *); extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); +extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, + dma_addr_t *dma); extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); extern void gen_pool_for_each_chunk(struct gen_pool *, void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); diff --git a/lib/genalloc.c b/lib/genalloc.c index 26cf20b..dda3116 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -313,6 +313,34 @@ retry: EXPORT_SYMBOL(gen_pool_alloc);
/** + * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage + * @pool: pool to allocate from + * @size: number of bytes to allocate from the pool + * @dma: dma-view physical address + * + * Allocate the requested number of bytes from the specified pool. + * Uses the pool allocation function (with first-fit algorithm by default). + * Can not be used in NMI handler on architectures without + * NMI-safe cmpxchg implementation. + */ +void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) +{ + unsigned long vaddr; + + if (!pool) + return NULL; + + vaddr = gen_pool_alloc(pool, size); + if (!vaddr) + return NULL; + + *dma = gen_pool_virt_to_phys(pool, vaddr); + + return (void *)vaddr; +} +EXPORT_SYMBOL(gen_pool_dma_alloc); + +/** * gen_pool_free - free allocated special memory back to the pool * @pool: pool to free to * @addr: starting address of memory to free back to pool
Since gen_pool_dma_alloc() is introduced, we implement it to simplify code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- arch/arm/mach-davinci/sram.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c index f18928b..8540ddd 100644 --- a/arch/arm/mach-davinci/sram.c +++ b/arch/arm/mach-davinci/sram.c @@ -25,7 +25,6 @@ struct gen_pool *sram_get_gen_pool(void)
void *sram_alloc(size_t len, dma_addr_t *dma) { - unsigned long vaddr; dma_addr_t dma_base = davinci_soc_info.sram_dma;
if (dma) @@ -33,13 +32,7 @@ void *sram_alloc(size_t len, dma_addr_t *dma) if (!sram_pool || (dma && !dma_base)) return NULL;
- vaddr = gen_pool_alloc(sram_pool, len); - if (!vaddr) - return NULL; - - if (dma) - *dma = gen_pool_virt_to_phys(sram_pool, vaddr); - return (void *)vaddr; + return gen_pool_dma_alloc(sram_pool, len, dma);
} EXPORT_SYMBOL(sram_alloc);
Since gen_pool_dma_alloc() is introduced, we implement it to simplify code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- drivers/dma/mmp_tdma.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index 2b4026d..3ddacc1 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -378,12 +378,7 @@ struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac) if (!gpool) return NULL;
- tdmac->desc_arr = (void *)gen_pool_alloc(gpool, size); - if (!tdmac->desc_arr) - return NULL; - - tdmac->desc_arr_phys = gen_pool_virt_to_phys(gpool, - (unsigned long)tdmac->desc_arr); + tdmac->desc_arr = gen_pool_dma_alloc(gpool, size, &tdmac->desc_arr_phys);
return tdmac->desc_arr; }
Since gen_pool_dma_alloc() is introduced, we implement it to simplify code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- drivers/media/platform/coda.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index ed4998c..bd72fb9 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -3298,13 +3298,12 @@ static int coda_probe(struct platform_device *pdev) dev->iram_size = CODA7_IRAM_SIZE; break; } - dev->iram_vaddr = gen_pool_alloc(dev->iram_pool, dev->iram_size); + dev->iram_vaddr = (unsigned long)gen_pool_dma_alloc(dev->iram_pool, + dev->iram_size, (dma_addr_t *)&dev->iram_paddr); if (!dev->iram_vaddr) { dev_err(&pdev->dev, "unable to alloc iram\n"); return -ENOMEM; } - dev->iram_paddr = gen_pool_virt_to_phys(dev->iram_pool, - dev->iram_vaddr);
platform_set_drvdata(pdev, dev);
Since gen_pool_dma_alloc() is introduced, we implement it to simplify code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- drivers/uio/uio_pruss.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index f519da9..96c4a19 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -158,14 +158,12 @@ static int pruss_probe(struct platform_device *dev) if (pdata->sram_pool) { gdev->sram_pool = pdata->sram_pool; gdev->sram_vaddr = - gen_pool_alloc(gdev->sram_pool, sram_pool_sz); + (unsigned long)gen_pool_dma_alloc(gdev->sram_pool, + sram_pool_sz, &gdev->sram_paddr); if (!gdev->sram_vaddr) { dev_err(&dev->dev, "Could not allocate SRAM pool\n"); goto out_free; } - gdev->sram_paddr = - gen_pool_virt_to_phys(gdev->sram_pool, - gdev->sram_vaddr); }
gdev->ddr_vaddr = dma_alloc_coherent(&dev->dev, extram_pool_sz,
Since gen_pool_dma_alloc() is introduced, we implement it to simplify code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- sound/core/memalloc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 9d93f02..5e1c7bc 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -184,11 +184,7 @@ static void snd_malloc_dev_iram(struct snd_dma_buffer *dmab, size_t size) /* Assign the pool into private_data field */ dmab->private_data = pool;
- dmab->area = (void *)gen_pool_alloc(pool, size); - if (!dmab->area) - return; - - dmab->addr = gen_pool_virt_to_phys(pool, (unsigned long)dmab->area); + dmab->area = gen_pool_dma_alloc(pool, size, &dmab->addr); }
/**
Since gen_pool_dma_alloc() is introduced, we implement it to simplify code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- sound/soc/davinci/davinci-pcm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 84a63c6..fa64cd8 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -267,10 +267,9 @@ static int allocate_sram(struct snd_pcm_substream *substream, return 0;
ppcm->period_bytes_max = size; - iram_virt = (void *)gen_pool_alloc(sram_pool, size); + iram_virt = gen_pool_dma_alloc(sram_pool, size, &iram_phys); if (!iram_virt) goto exit1; - iram_phys = gen_pool_virt_to_phys(sram_pool, (unsigned)iram_virt); iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL); if (!iram_dma) goto exit2;
Since gen_pool_dma_alloc() is introduced, we implement it to simplify code.
Signed-off-by: Nicolin Chen b42378@freescale.com --- sound/soc/pxa/mmp-pcm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 8235e23..7929e19 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -201,10 +201,9 @@ static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream, if (!gpool) return -ENOMEM;
- buf->area = (unsigned char *)gen_pool_alloc(gpool, size); + buf->area = gen_pool_dma_alloc(gpool, size, &buf->addr); if (!buf->area) return -ENOMEM; - buf->addr = gen_pool_virt_to_phys(gpool, (unsigned long)buf->area); buf->bytes = size; return 0; }
participants (1)
-
Nicolin Chen