summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/clockdomain.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-11-30 06:49:30 (GMT)
committerOlof Johansson <olof@lixom.net>2012-11-30 06:49:30 (GMT)
commit9121dfca73d81fa886f15610cac2bf372391f3eb (patch)
tree9aff09bb821f632ea6b7a1117c094d662eb2ecd3 /arch/arm/mach-omap2/clockdomain.c
parent77f9db89c928773e5fb1df0df4d13d5cc8abd178 (diff)
parent8b9c1ac2e11a9fb3a5a8860fb7570ff7633aa7f7 (diff)
downloadlinux-fsl-qoriq-9121dfca73d81fa886f15610cac2bf372391f3eb.tar.xz
Merge tag 'omap-for-v3.8/devel-prcm-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/pm2
From Tony Lindgren: omap prcm changes via Paul Walmsley <paul@pwsan.com>: Some miscellaneous OMAP hwmod changes for 3.8, along with a PRM change needed for one of the hwmod patches to function. Basic test logs for this branch on top of Tony's omap-for-v3.8/clock branch at commit 558a0780b0a04862a678f7823215424b4e5501f9 are here: http://www.pwsan.com/omap/testlogs/hwmod_devel_a_3.8/20121121161522/ However, omap-for-v3.8/clock at 558a0780 does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_hwmod_devel_a_3.8/20121121162719/ which indicate that the series tests cleanly. * tag 'omap-for-v3.8/devel-prcm-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (49 commits) ARM: OMAP2+: omap_device: Correct resource handling for DT boot ARM: OMAP2+: hwmod: Add possibility to count hwmod resources based on type ARM: OMAP2+: hwmod: Add support for per hwmod/module context lost count ARM: OMAP2+: PRM: initialize some PRM functions early ARM: OMAP2+: clock: Cleanup !CONFIG_COMMON_CLK parts ARM: OMAP2xxx: clock: drop obsolete clock data ARM: OMAP2: clock: Cleanup !CONFIG_COMMON_CLK parts ARM: OMAP3+: DPLL: drop !CONFIG_COMMON_CLK sections ARM: AM33xx: clock: drop obsolete clock data ARM: OMAP3xxx: clk: drop obsolete clock data ARM: OMAP3: clock: Cleanup !CONFIG_COMMON_CLK parts ARM: OMAP44xx: clock: drop obsolete clock data ARM: OMAP4: clock: Cleanup !CONFIG_COMMON_CLK parts ARM: OMAP: hwmod: Cleanup !CONFIG_COMMON_CLK parts ARM: OMAP: clock: Switch to COMMON clk ARM: OMAP2: clock: Add 24xx data using common struct clk ARM: OMAP3: clock: Add 3xxx data using common struct clk ARM: AM33XX: clock: add clock data in common clock format ARM: OMAP4: clock: Add 44xx data using common struct clk ARM: OMAP2+: clock: add OMAP CCF convenience macros to mach-omap2/clock.h ... Some context conflicts due to nearby changes resolved in arch/arm/mach-omap2/io.c. Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-omap2/clockdomain.c')
-rw-r--r--arch/arm/mach-omap2/clockdomain.c89
1 files changed, 52 insertions, 37 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 64e5046..3848735 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/limits.h>
#include <linux/err.h>
+#include <linux/clk-provider.h>
#include <linux/io.h>
@@ -947,35 +948,6 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
return 0;
}
-static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)
-{
- unsigned long flags;
-
- if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
- return -EINVAL;
-
- spin_lock_irqsave(&clkdm->lock, flags);
-
- if (atomic_read(&clkdm->usecount) == 0) {
- spin_unlock_irqrestore(&clkdm->lock, flags);
- WARN_ON(1); /* underflow */
- return -ERANGE;
- }
-
- if (atomic_dec_return(&clkdm->usecount) > 0) {
- spin_unlock_irqrestore(&clkdm->lock, flags);
- return 0;
- }
-
- arch_clkdm->clkdm_clk_disable(clkdm);
- pwrdm_state_switch(clkdm->pwrdm.ptr);
- spin_unlock_irqrestore(&clkdm->lock, flags);
-
- pr_debug("clockdomain: %s: disabled\n", clkdm->name);
-
- return 0;
-}
-
/**
* clkdm_clk_enable - add an enabled downstream clock to this clkdm
* @clkdm: struct clockdomain *
@@ -1018,15 +990,37 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
*/
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
{
- /*
- * XXX Rewrite this code to maintain a list of enabled
- * downstream clocks for debugging purposes?
- */
+ unsigned long flags;
- if (!clk)
+ if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
return -EINVAL;
- return _clkdm_clk_hwmod_disable(clkdm);
+ spin_lock_irqsave(&clkdm->lock, flags);
+
+ /* corner case: disabling unused clocks */
+ if (__clk_get_enable_count(clk) == 0)
+ goto ccd_exit;
+
+ if (atomic_read(&clkdm->usecount) == 0) {
+ spin_unlock_irqrestore(&clkdm->lock, flags);
+ WARN_ON(1); /* underflow */
+ return -ERANGE;
+ }
+
+ if (atomic_dec_return(&clkdm->usecount) > 0) {
+ spin_unlock_irqrestore(&clkdm->lock, flags);
+ return 0;
+ }
+
+ arch_clkdm->clkdm_clk_disable(clkdm);
+ pwrdm_state_switch(clkdm->pwrdm.ptr);
+
+ pr_debug("clockdomain: %s: disabled\n", clkdm->name);
+
+ccd_exit:
+ spin_unlock_irqrestore(&clkdm->lock, flags);
+
+ return 0;
}
/**
@@ -1077,6 +1071,8 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
*/
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
{
+ unsigned long flags;
+
/* The clkdm attribute does not exist yet prior OMAP4 */
if (cpu_is_omap24xx() || cpu_is_omap34xx())
return 0;
@@ -1086,9 +1082,28 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
* downstream hwmods for debugging purposes?
*/
- if (!oh)
+ if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
return -EINVAL;
- return _clkdm_clk_hwmod_disable(clkdm);
+ spin_lock_irqsave(&clkdm->lock, flags);
+
+ if (atomic_read(&clkdm->usecount) == 0) {
+ spin_unlock_irqrestore(&clkdm->lock, flags);
+ WARN_ON(1); /* underflow */
+ return -ERANGE;
+ }
+
+ if (atomic_dec_return(&clkdm->usecount) > 0) {
+ spin_unlock_irqrestore(&clkdm->lock, flags);
+ return 0;
+ }
+
+ arch_clkdm->clkdm_clk_disable(clkdm);
+ pwrdm_state_switch(clkdm->pwrdm.ptr);
+ spin_unlock_irqrestore(&clkdm->lock, flags);
+
+ pr_debug("clockdomain: %s: disabled\n", clkdm->name);
+
+ return 0;
}