From 6c69abb27f1a7e2c15a678fb9e7ab55293c8f820 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Tue, 19 Oct 2010 18:44:16 +0900 Subject: 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 Acked-by: Jassi Brar [kgene.kim@samsung.com: minor title and comment edit] Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/s3c-pl330.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'arch/arm/plat-samsung') diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c index a91305a60aed..b4ff8d74ac40 100644 --- a/arch/arm/plat-samsung/s3c-pl330.c +++ b/arch/arm/plat-samsung/s3c-pl330.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include @@ -27,6 +29,7 @@ * @node: To attach to the global list of DMACs. * @pi: PL330 configuration info for the DMAC. * @kmcache: Pool to quickly allocate xfers for all channels in the dmac. + * @clk: Pointer of DMAC operation clock. */ struct s3c_pl330_dmac { unsigned busy_chan; @@ -34,6 +37,7 @@ struct s3c_pl330_dmac { struct list_head node; struct pl330_info *pi; struct kmem_cache *kmcache; + struct clk *clk; }; /** @@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev) if (ret) goto probe_err4; - ret = pl330_add(pl330_info); - if (ret) - goto probe_err5; - /* Allocate a new DMAC */ s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); if (!s3c_pl330_dmac) { 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; } + clk_enable(s3c_pl330_dmac->clk); + + ret = pl330_add(pl330_info); + if (ret) + goto probe_err7; /* Hook the info */ s3c_pl330_dmac->pi = pl330_info; @@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev) if (!s3c_pl330_dmac->kmcache) { ret = -ENOMEM; - goto probe_err7; + goto probe_err8; } /* Get the list of peripherals */ @@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev) return 0; +probe_err8: + pl330_del(pl330_info); probe_err7: - kfree(s3c_pl330_dmac); + clk_disable(s3c_pl330_dmac->clk); + clk_put(s3c_pl330_dmac->clk); probe_err6: - pl330_del(pl330_info); + kfree(s3c_pl330_dmac); probe_err5: free_irq(irq, pl330_info); 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 */ list_del(&dmac->node); kfree(dmac); -- cgit v1.2.3