]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00174732 ASRC:close core clock if ASRC idle
authorChen Liangjun <b36089@freescale.com>
Thu, 16 Feb 2012 08:15:36 +0000 (16:15 +0800)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:10:58 +0000 (14:10 +0200)
Close ASRC core clock when ASRC device is not used.

Open ASRC core clock when an ASRC device is open. Close ASRC core
clock when an ASRC device is close.

Signed-off-by: Chen Liangjun <b36089@freescale.com>
drivers/mxc/asrc/mxc_asrc.c
include/linux/mxc_asrc.h

index dbf3fffcb1003811f8efb46f193b977af66867e7..0a3860afc986299fa5359a19cc7b9d4d37b2d9d0 100644 (file)
@@ -51,6 +51,7 @@ static struct class *asrc_class;
 DEFINE_SPINLOCK(data_lock);
 DEFINE_SPINLOCK(input_int_lock);
 DEFINE_SPINLOCK(output_int_lock);
+DEFINE_SPINLOCK(asrc_clock_lock);
 
 #define AICPA          0       /* Input Clock Divider A Offset */
 #define AICDA          3       /* Input Clock Prescaler A Offset */
@@ -609,7 +610,6 @@ void asrc_start_conv(enum asrc_pair_index index)
        reg = __raw_readl(asrc_vrt_base_addr + ASRC_ASRCTR_REG);
        if ((reg & 0x0E) == 0)
                clk_enable(mxc_asrc_data->asrc_audio_clk);
-
        reg |= (1 << (1 + index));
        __raw_writel(reg, asrc_vrt_base_addr + ASRC_ASRCTR_REG);
 
@@ -1399,7 +1399,6 @@ static long asrc_ioctl(struct file *file,
                                err = -EFAULT;
                                break;
                        }
-
                        spin_lock_irqsave(&input_int_lock, lock_flags);
                        if (params->input_queue_empty == 0) {
                                err = -EFAULT;
@@ -1524,6 +1523,13 @@ static int mxc_asrc_open(struct inode *inode, struct file *file)
 {
        int err = 0;
        struct asrc_pair_params *pair_params;
+       unsigned long lock_flags;
+
+       spin_lock_irqsave(&asrc_clock_lock, lock_flags);
+       g_asrc_data->counter++;
+       clk_enable(mxc_asrc_data->asrc_core_clk);
+       spin_unlock_irqrestore(&asrc_clock_lock, lock_flags);
+
        if (signal_pending(current))
                return -EINTR;
        pair_params = kzalloc(sizeof(struct asrc_pair_params), GFP_KERNEL);
@@ -1548,7 +1554,9 @@ static int mxc_asrc_open(struct inode *inode, struct file *file)
 static int mxc_asrc_close(struct inode *inode, struct file *file)
 {
        struct asrc_pair_params *pair_params;
+       unsigned long lock_flags;
        pair_params = file->private_data;
+
        if (pair_params->asrc_active == 1) {
                dmaengine_terminate_all(pair_params->input_dma_channel);
                dmaengine_terminate_all(pair_params->output_dma_channel);
@@ -1562,8 +1570,15 @@ static int mxc_asrc_close(struct inode *inode, struct file *file)
                mxc_free_dma_buf(pair_params);
                asrc_release_pair(pair_params->index);
        }
+
        kfree(pair_params);
        file->private_data = NULL;
+
+       spin_lock_irqsave(&asrc_clock_lock, lock_flags);
+       g_asrc_data->counter--;
+       if (g_asrc_data->counter == 0)
+               clk_disable(mxc_asrc_data->asrc_core_clk);
+       spin_unlock_irqrestore(&asrc_clock_lock, lock_flags);
        return 0;
 }
 
@@ -1713,6 +1728,7 @@ static int mxc_asrc_probe(struct platform_device *pdev)
        g_asrc_data->asrc_pair[0].overload_error = 0;
        g_asrc_data->asrc_pair[1].overload_error = 0;
        g_asrc_data->asrc_pair[2].overload_error = 0;
+       g_asrc_data->counter = 0;
 
        asrc_major = register_chrdev(asrc_major, "mxc_asrc", &asrc_fops);
        if (asrc_major < 0) {
@@ -1740,6 +1756,7 @@ static int mxc_asrc_probe(struct platform_device *pdev)
 
        mxc_asrc_data =
            (struct imx_asrc_platform_data *)pdev->dev.platform_data;
+
        clk_enable(mxc_asrc_data->asrc_core_clk);
 
        switch (mxc_asrc_data->clk_map_ver) {
@@ -1786,7 +1803,7 @@ static int mxc_asrc_probe(struct platform_device *pdev)
        err = mxc_init_asrc();
        if (err < 0)
                goto err_out_class;
-
+       clk_disable(mxc_asrc_data->asrc_core_clk);
        goto out;
 
       err_out_class:
index a8d8b8bc474ac6ca6e19c19056ccb91df14604a4..516b0b69f286ff58a0b9a526d14f3e0ff7e2b2cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -197,6 +197,7 @@ struct asrc_pair_params {
 
 struct asrc_data {
        struct asrc_pair asrc_pair[3];
+       unsigned int     counter;
 };
 
 extern int asrc_req_pair(int chn_num, enum asrc_pair_index *index);