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:39:32 +0800
commit6bb16bcc9ed80b217b6fda41d84d9af222eb532a (patch)
tree206a581916e10e8fec6bfb101ca4f93ef9b5e4f0
parent95b9c1b0f374328b29018f094b31cece0e72030c (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;
}