diff options
author | Chen Liangjun <b36089@freescale.com> | 2012-02-14 11:23:30 +0800 |
---|---|---|
committer | Chen Liangjun <b36089@freescale.com> | 2012-02-14 17:36:14 +0800 |
commit | cb02a3be21ed06a61437e78a91a84aee6094df35 (patch) | |
tree | 17a23802c28a9e1b5aa06bcba5af96b29772bcce | |
parent | 2d63f1aa1b9f46f349bc9fe37349c5d8e1c9edba (diff) |
ENGR00174399 ASRC: fix mmap fail bug
If output sample rate is less than input sample rate, it is possible
that the address of output dma buffer 0 can not be divided by page size.
Thus the mmap of output dma in the user space would fail and test
would fail.
let all output dma buffers allocate dma buffer together and we can
assure that the address of output dma buffer 0 can be divided by
page size.
Signed-off-by: Chen Liangjun <b36089@freescale.com>
-rw-r--r-- | drivers/mxc/asrc/mxc_asrc.c | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c index bf36aec4bd34..dbf3fffcb100 100644 --- a/drivers/mxc/asrc/mxc_asrc.c +++ b/drivers/mxc/asrc/mxc_asrc.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -890,14 +890,19 @@ static void asrc_output_dma_callback(void *data) static void mxc_free_dma_buf(struct asrc_pair_params *params) { int i; - for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) { - if (params->input_dma[i].dma_vaddr != NULL) { - kfree(params->input_dma[i].dma_vaddr); + + if (params->input_dma[0].dma_vaddr != NULL) { + kfree(params->input_dma[0].dma_vaddr); + for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) { params->input_dma[i].dma_vaddr = NULL; + params->input_dma[i].dma_paddr = 0; } - if (params->output_dma[i].dma_vaddr != NULL) { - kfree(params->output_dma[i].dma_vaddr); + } + if (params->output_dma[0].dma_vaddr != NULL) { + kfree(params->output_dma[0].dma_vaddr); + for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) { params->output_dma[i].dma_vaddr = NULL; + params->output_dma[i].dma_paddr = 0; } } @@ -907,9 +912,23 @@ static void mxc_free_dma_buf(struct asrc_pair_params *params) static int mxc_allocate_dma_buf(struct asrc_pair_params *params) { int i; + + params->input_dma[0].dma_vaddr = NULL; + params->input_dma[0].dma_vaddr = + kzalloc(params->input_buffer_size * ASRC_DMA_BUFFER_NUM, + GFP_KERNEL); + + if (!params->input_dma[0].dma_vaddr) { + mxc_free_dma_buf(params); + pr_info("can't allocate buff\n"); + return -ENOBUFS; + } + for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) { params->input_dma[i].dma_vaddr = - kzalloc(params->input_buffer_size, GFP_KERNEL); + (unsigned char *) + ((unsigned long)params->input_dma[0].dma_vaddr + + i * params->input_buffer_size); params->input_dma[i].dma_paddr = virt_to_dma(NULL, params->input_dma[i].dma_vaddr); if (params->input_dma[i].dma_vaddr == NULL) { @@ -918,17 +937,30 @@ static int mxc_allocate_dma_buf(struct asrc_pair_params *params) return -ENOBUFS; } } + + params->output_dma[0].dma_vaddr = NULL; + params->output_dma[0].dma_vaddr = + kzalloc(params->output_buffer_size * ASRC_DMA_BUFFER_NUM, + GFP_KERNEL); + if (!params->output_dma[0].dma_vaddr) { + mxc_free_dma_buf(params); + pr_info("can't allocate buff\n"); + return -ENOBUFS; + } + for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) { params->output_dma[i].dma_vaddr = - kzalloc(params->output_buffer_size, GFP_KERNEL); + (unsigned char *) + ((unsigned long)params->output_dma[0].dma_vaddr + + i * params->output_buffer_size); params->output_dma[i].dma_paddr = virt_to_dma(NULL, params->output_dma[i].dma_vaddr); if (params->output_dma[i].dma_vaddr == NULL) { mxc_free_dma_buf(params); + pr_info("can't allocate buff\n"); return -ENOBUFS; } } - return 0; } |