From 4fdaa5078c6cc77cc0d9eaec51a2011b7c1861ce Mon Sep 17 00:00:00 2001 From: Zeng Zhaoming Date: Tue, 12 Jul 2011 05:55:32 +0800 Subject: [PATCH] ENGR00144281 SDMA: System hangs in bootup when kernel_preempt not enable When kernel_preempt not enable in configure, system bootup hangs in sdma initialization. This is caused by sdma initialization waiting for channel0 complete loading script in queue, and arch_idle happens with action to disable some clocks, if DDR clock disabled, script loading will failed and SoC hangs. Solve it by make sure DDR clock is enabled during sdma initialization. Signed-off-by: Zeng Zhaoming --- arch/arm/plat-mxc/sdma/sdma.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-mxc/sdma/sdma.c b/arch/arm/plat-mxc/sdma/sdma.c index 120f5d5afa4..218bd850077 100644 --- a/arch/arm/plat-mxc/sdma/sdma.c +++ b/arch/arm/plat-mxc/sdma/sdma.c @@ -1437,14 +1437,26 @@ int sdma_probe(struct platform_device *pdev) int irq; struct resource *rsrc; configs_data confreg_data; + char *ddr_clk_name = "emi_fast_clk"; + struct clk *mem_clock; + + if (cpu_is_mx50()) + ddr_clk_name = "ddr_clk"; /* Initialize to the default values */ confreg_data = iapi_ConfigDefaults; confreg_data.dspdma = 0; /* Set ACR bit */ - mxc_sdma_ahb_clk = clk_get(NULL, "sdma_ahb_clk"); - mxc_sdma_ipg_clk = clk_get(NULL, "sdma_ipg_clk"); + mem_clock = clk_get(&pdev->dev, ddr_clk_name); + if (!mem_clock) { + printk(KERN_ERR"can't get ddr memory clock\n"); + return -ENODEV; + } + + clk_enable(mem_clock); + mxc_sdma_ahb_clk = clk_get(&pdev->dev, "sdma_ahb_clk"); + mxc_sdma_ipg_clk = clk_get(&pdev->dev, "sdma_ipg_clk"); clk_enable(mxc_sdma_ahb_clk); clk_enable(mxc_sdma_ipg_clk); if (clk_get_rate(mxc_sdma_ahb_clk) / clk_get_rate(mxc_sdma_ipg_clk) < 2) { @@ -1502,12 +1514,14 @@ int sdma_probe(struct platform_device *pdev) clk_disable(mxc_sdma_ahb_clk); clk_disable(mxc_sdma_ipg_clk); + clk_disable(mem_clock); return res; sdma_init_fail: printk(KERN_ERR "Error 0x%x in sdma_init\n", res); clk_disable(mxc_sdma_ahb_clk); clk_disable(mxc_sdma_ipg_clk); + clk_disable(mem_clock); return res; }