summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen Liangjun <b36089@freescale.com>2012-02-14 11:23:30 +0800
committerChen Liangjun <b36089@freescale.com>2012-02-14 17:36:14 +0800
commitcb02a3be21ed06a61437e78a91a84aee6094df35 (patch)
tree17a23802c28a9e1b5aa06bcba5af96b29772bcce
parent2d63f1aa1b9f46f349bc9fe37349c5d8e1c9edba (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.c50
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;
}