ARM: SAMSUNG: Move DMA clock enable into S3C PL330 driver

This patch moves DMA clock enable functionality into pl330_probe() of
plat-samsung/s3c_pl330.c (PL330 DMAC driver) and disable functionality
into pl330_remove().
For now according to clock policy of Samsung SoCs' mainline, clocks which
are used in the driver should be controlled by each own.

Signed-off-by: Seungwhan Youn <sw.youn@samsung.com>
Acked-by: Jassi Brar <jassi.brar@samsung.com>
[kgene.kim@samsung.com: minor title and comment edit]
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
This commit is contained in:
Seungwhan Youn 2010-10-19 18:44:16 +09:00 committed by Kukjin Kim
parent 9d59c17ab5
commit 6c69abb27f
1 changed files with 28 additions and 8 deletions

View File

@ -15,6 +15,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm/hardware/pl330.h> #include <asm/hardware/pl330.h>
@ -27,6 +29,7 @@
* @node: To attach to the global list of DMACs. * @node: To attach to the global list of DMACs.
* @pi: PL330 configuration info for the DMAC. * @pi: PL330 configuration info for the DMAC.
* @kmcache: Pool to quickly allocate xfers for all channels in the dmac. * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
* @clk: Pointer of DMAC operation clock.
*/ */
struct s3c_pl330_dmac { struct s3c_pl330_dmac {
unsigned busy_chan; unsigned busy_chan;
@ -34,6 +37,7 @@ struct s3c_pl330_dmac {
struct list_head node; struct list_head node;
struct pl330_info *pi; struct pl330_info *pi;
struct kmem_cache *kmcache; struct kmem_cache *kmcache;
struct clk *clk;
}; };
/** /**
@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev)
if (ret) if (ret)
goto probe_err4; goto probe_err4;
ret = pl330_add(pl330_info);
if (ret)
goto probe_err5;
/* Allocate a new DMAC */ /* Allocate a new DMAC */
s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
if (!s3c_pl330_dmac) { if (!s3c_pl330_dmac) {
ret = -ENOMEM; ret = -ENOMEM;
goto probe_err5;
}
/* Get operation clock and enable it */
s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
if (IS_ERR(s3c_pl330_dmac->clk)) {
dev_err(&pdev->dev, "Cannot get operation clock.\n");
ret = -EINVAL;
goto probe_err6; goto probe_err6;
} }
clk_enable(s3c_pl330_dmac->clk);
ret = pl330_add(pl330_info);
if (ret)
goto probe_err7;
/* Hook the info */ /* Hook the info */
s3c_pl330_dmac->pi = pl330_info; s3c_pl330_dmac->pi = pl330_info;
@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev)
if (!s3c_pl330_dmac->kmcache) { if (!s3c_pl330_dmac->kmcache) {
ret = -ENOMEM; ret = -ENOMEM;
goto probe_err7; goto probe_err8;
} }
/* Get the list of peripherals */ /* Get the list of peripherals */
@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev)
return 0; return 0;
probe_err7: probe_err8:
kfree(s3c_pl330_dmac);
probe_err6:
pl330_del(pl330_info); pl330_del(pl330_info);
probe_err7:
clk_disable(s3c_pl330_dmac->clk);
clk_put(s3c_pl330_dmac->clk);
probe_err6:
kfree(s3c_pl330_dmac);
probe_err5: probe_err5:
free_irq(irq, pl330_info); free_irq(irq, pl330_info);
probe_err4: probe_err4:
@ -1188,6 +1204,10 @@ static int pl330_remove(struct platform_device *pdev)
} }
} }
/* Disable operation clock */
clk_disable(dmac->clk);
clk_put(dmac->clk);
/* Remove the DMAC */ /* Remove the DMAC */
list_del(&dmac->node); list_del(&dmac->node);
kfree(dmac); kfree(dmac);