summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen Liangjun <b36089@freescale.com>2012-03-23 20:22:01 +0800
committerChen Liangjun <b36089@freescale.com>2012-03-28 13:58:31 +0800
commit0fa1ff4cc96330800640f32f1d825b2ba1b270ec (patch)
tree520b85f3ef2b24c1385cb3f105cb7e20c6f678c8
parentdaa4fa661c03d848b66d179a93af39f4add23020 (diff)
ENGR00177302 ASRC: change clock management
1 close clock when asrc is not working. 2 enable the asrc core clock when user sucessfully request an ASRC pair and disable it when the pair is release.So the call from ESAI using the p2p DMA mode can be support. Signed-off-by: Chen Liangjun <b36089@freescale.com>
-rw-r--r--drivers/mxc/asrc/mxc_asrc.c30
-rw-r--r--include/linux/mxc_asrc.h2
2 files changed, 22 insertions, 10 deletions
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c
index 41e3f707dfcd..b4ec41ad90da 100644
--- a/drivers/mxc/asrc/mxc_asrc.c
+++ b/drivers/mxc/asrc/mxc_asrc.c
@@ -341,6 +341,11 @@ int asrc_req_pair(int chn_num, enum asrc_pair_index *index)
}
}
spin_unlock_irqrestore(&data_lock, lock_flags);
+
+ if (!err) {
+ clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
+ clk_enable(g_asrc->mxc_asrc_data->asrc_audio_clk);
+ }
return err;
}
@@ -595,10 +600,7 @@ void asrc_start_conv(enum asrc_pair_index index)
int i;
spin_lock_irqsave(&data_lock, lock_flags);
-
reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
- if ((reg & 0x0E) == 0)
- clk_enable(g_asrc->mxc_asrc_data->asrc_audio_clk);
reg |= (1 << (1 + index));
__raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
@@ -650,14 +652,22 @@ void asrc_stop_conv(enum asrc_pair_index index)
reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
reg &= ~(1 << (1 + index));
__raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
- if ((reg & 0x0E) == 0)
- clk_disable(g_asrc->mxc_asrc_data->asrc_audio_clk);
spin_unlock_irqrestore(&data_lock, lock_flags);
+
return;
}
EXPORT_SYMBOL(asrc_stop_conv);
+void asrc_finish_conv(enum asrc_pair_index index)
+{
+ clk_disable(g_asrc->mxc_asrc_data->asrc_audio_clk);
+ clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
+
+ return;
+}
+EXPORT_SYMBOL(asrc_finish_conv);
+
int asrc_get_dma_request(enum asrc_pair_index index, bool in)
{
if (in)
@@ -665,6 +675,7 @@ int asrc_get_dma_request(enum asrc_pair_index index, bool in)
else
return g_asrc->dmatx[index];
}
+
EXPORT_SYMBOL(asrc_get_dma_request);
/*!
@@ -753,6 +764,7 @@ u32 asrc_get_per_addr(enum asrc_pair_index index, bool in)
else
return g_asrc->paddr + ASRC_ASRDOA_REG + (index << 3);
}
+
EXPORT_SYMBOL(asrc_get_per_addr);
static int mxc_init_asrc(void)
@@ -1132,6 +1144,7 @@ static long asrc_ioctl(struct file *file,
mxc_free_dma_buf(params);
asrc_release_pair(index);
+ asrc_finish_conv(index);
params->pair_hold = 0;
break;
}
@@ -1430,7 +1443,6 @@ static int mxc_asrc_open(struct inode *inode, struct file *file)
int err = 0;
struct asrc_pair_params *pair_params;
- clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
if (signal_pending(current))
return -EINTR;
pair_params = kzalloc(sizeof(struct asrc_pair_params), GFP_KERNEL);
@@ -1438,7 +1450,6 @@ static int mxc_asrc_open(struct inode *inode, struct file *file)
pr_debug("Failed to allocate pair_params\n");
err = -ENOBUFS;
}
- clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
file->private_data = pair_params;
return err;
}
@@ -1474,10 +1485,10 @@ static int mxc_asrc_close(struct inode *inode, struct file *file)
pair_params->output_dma_channel);
mxc_free_dma_buf(pair_params);
asrc_release_pair(pair_params->index);
+ asrc_finish_conv(pair_params->index);
}
kfree(pair_params);
file->private_data = NULL;
- clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
}
return 0;
}
@@ -1712,11 +1723,9 @@ static int mxc_asrc_probe(struct platform_device *pdev)
if (err < 0)
goto err_out_class;
- clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
goto out;
err_out_class:
- clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
device_destroy(g_asrc->asrc_class, MKDEV(g_asrc->asrc_major, 0));
class_destroy(g_asrc->asrc_class);
err_out_chrdev:
@@ -1724,6 +1733,7 @@ static int mxc_asrc_probe(struct platform_device *pdev)
error:
kfree(g_asrc);
out:
+ clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
pr_info("mxc_asrc registered\n");
return err;
}
diff --git a/include/linux/mxc_asrc.h b/include/linux/mxc_asrc.h
index c5b1d3e312ba..6de6a7e3cd86 100644
--- a/include/linux/mxc_asrc.h
+++ b/include/linux/mxc_asrc.h
@@ -230,6 +230,8 @@ extern void asrc_start_conv(enum asrc_pair_index index);
extern void asrc_stop_conv(enum asrc_pair_index index);
extern u32 asrc_get_per_addr(enum asrc_pair_index index, bool i);
extern int asrc_get_dma_request(enum asrc_pair_index index, bool i);
+extern void asrc_finish_conv(enum asrc_pair_index index);
+
#endif /* __kERNEL__ */
#endif /* __MXC_ASRC_H__ */