From: Seungwhan Youn Date: Tue, 19 Oct 2010 09:44:16 +0000 (+0900) Subject: ARM: SAMSUNG: Move DMA clock enable into S3C PL330 driver X-Git-Tag: firefly_0821_release~7613^2~3546^2^2~2^2~11 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6c69abb27f1a7e2c15a678fb9e7ab55293c8f820;p=firefly-linux-kernel-4.4.55.git 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 --- 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);