diff options
author | Ranjani Vaidyanathan <ra5478@freescale.com> | 2012-08-30 15:02:32 -0500 |
---|---|---|
committer | Eric Nelson <eric.nelson@boundarydevices.com> | 2012-10-12 07:12:00 -0700 |
commit | 71a7cccf4d00a69177649e4862e9e944ce3abf34 (patch) | |
tree | 28f7353eafaa3efd2ff6004607de33cb9210d000 /arch/arm/mach-mx6/clock.c | |
parent | d7ec33a2aaf9f0a2dd86cc8a1e415e91317b6f8e (diff) |
ENGR00222134 MX6x - Fix race-conditions in low power code.
Fix couple of race-conditions associated with low power IDLE code:
1. Ensure that bus freq mutex is used in the suspend/resume function
2. Ensure that the usecount of pll2 is incremented/decremented when
ARM is switched to run from PLL2_PFD_400. And PLL2 is enabled/disabled
when necessary.
Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx6/clock.c')
-rw-r--r-- | arch/arm/mach-mx6/clock.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index c2bf20177909..8b75aee78964 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -1261,7 +1261,16 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) * PLL2_PFD_400M. */ if (pll1_sw_clk.parent != &pll2_pfd_400M) { - pll2_pfd_400M.enable(&pll2_pfd_400M); + if (pll2_pfd_400M.usecount == 0) { + /* Check if PLL2 needs to be enabled also. */ + if (pll2_528_bus_main_clk.usecount == 0) + pll2_528_bus_main_clk.enable(&pll2_528_bus_main_clk); + /* Ensure parent usecount is + * also incremented. + */ + pll2_528_bus_main_clk.usecount++; + pll2_pfd_400M.enable(&pll2_pfd_400M); + } pll2_pfd_400M.usecount++; arm_needs_pll2_400 = true; pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M); @@ -1288,11 +1297,19 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); pll1_sw_clk.parent = &pll1_sys_main_clk; - if (arm_needs_pll2_400) + if (arm_needs_pll2_400) { pll2_pfd_400M.usecount--; + if (pll2_pfd_400M.usecount == 0) { + pll2_pfd_400M.disable(&pll2_pfd_400M); + /* Ensure parent usecount is + * also decremented. + */ + pll2_528_bus_main_clk.usecount--; + if (pll2_528_bus_main_clk.usecount == 0) + pll2_528_bus_main_clk.disable(&pll2_528_bus_main_clk); + } + } arm_needs_pll2_400 = false; - if (pll2_pfd_400M.usecount == 0) - pll2_pfd_400M.disable(&pll2_pfd_400M); } parent_rate = clk_get_rate(clk->parent); div = parent_rate / rate; |