From 563e41b56a9ef4906c2c561c387c8189e9cf0b77 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 13 Aug 2013 09:16:52 +0800 Subject: [PATCH] ENGR00269945: ARM: imx6sl: initialize use count of IPG clock We're running into a system hang during imx6sl boot. It's been tracked down to SDMA driver function sdma_init(). System hangs immediately after the clk_disable() is called in sdma_init(). It turns out that the issue is caused by IPG bus clock which is the parent of sdma clock is turned off accidentally due to the incorrect initial use count. IPG clock is initial on and should be always on when system operates. But the use count of the clock is zero initially. So when the last child clock gets disabled, the use count of IPG clock reaches zero, and thus clock framework will turn off IPG clock (and possibly parent clocks along the way), and causes the system hang. Let's initialize the use count of IPG clock by calling clk_prepare_enable() on it to match the on state of the clock, so that the clock will not be turned off accidentally. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6sl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index b96234338e9f..7a8d13a65c99 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -71,6 +71,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) struct device_node *np; void __iomem *base; int irq; + int ret; int i; clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); @@ -253,6 +254,15 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clk_register_clkdev(clks[IMX6SL_CLK_GPT], "ipg", "imx-gpt.0"); clk_register_clkdev(clks[IMX6SL_CLK_GPT_SERIAL], "per", "imx-gpt.0"); + /* + * To prevent the bus clock from being disabled accidently when + * clk_disable() gets called on child clock, let's increment the use + * count of IPG clock by initially calling clk_prepare_enable() on it. + */ + ret = clk_prepare_enable(clks[IMX6SL_CLK_IPG]); + if (ret) + pr_warn("%s: failed to enable IPG clock %d\n", __func__, ret); + if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]); clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]); -- 2.39.5