summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2012-11-09 14:13:43 -0800
committerTony Lindgren <tony@atomide.com>2012-11-09 14:13:43 -0800
commitc9d501e5cb0238910337213e12a09127221c35d8 (patch)
treea38418dc6a18b4138abbc81bb147d8aae0156f89 /arch/arm/mach-omap2/clock.c
parent7fc54fd3084457c7f11b9e2e1e3fcd19a3badc33 (diff)
parentb99db36cdf37decb1b5575c5f293d170cbbc53d6 (diff)
Merge tag 'omap-cleanup-b2-for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.8/cleanup-prcm
Second set of OMAP PRCM cleanups for 3.8. These patches remove the use of omap_prcm_get_reset_sources() from the OMAP watchdog driver, and remove mach-omap2/prcm.c and plat-omap/include/plat/prcm.h. Basic test logs for this branch on top of Tony's cleanup-prcm branch at commit 7fc54fd3084457c7f11b9e2e1e3fcd19a3badc33 are here: http://www.pwsan.com/omap/testlogs/prcm_cleanup_b_3.8/20121108151646/ However, cleanup-prcm at 7fc54fd3 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_prcm_cleanup_b_3.8/20121108151930/ which indicate that the series tests cleanly. This second pull request updates one of the patches which broke with rmk's allnoconfigs, and also updates the tag description to indicate that 7fc54fd3 is building cleanly here.
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 9205ea7d8dde..e381d991092c 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -26,17 +26,24 @@
#include <asm/cpu.h>
-#include <plat/prcm.h>
#include <trace/events/power.h>
#include "soc.h"
#include "clockdomain.h"
#include "clock.h"
+#include "cm.h"
#include "cm2xxx.h"
#include "cm3xxx.h"
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"
+#include "common.h"
+
+/*
+ * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait
+ * for a module to indicate that it is no longer in idle
+ */
+#define MAX_MODULE_ENABLE_WAIT 100000
u16 cpu_mask;
@@ -58,6 +65,40 @@ static DEFINE_SPINLOCK(clockfw_lock);
/* Private functions */
+
+/**
+ * _wait_idlest_generic - wait for a module to leave the idle state
+ * @reg: virtual address of module IDLEST register
+ * @mask: value to mask against to determine if the module is active
+ * @idlest: idle state indicator (0 or 1) for the clock
+ * @name: name of the clock (for printk)
+ *
+ * Wait for a module to leave idle, where its idle-status register is
+ * not inside the CM module. Returns 1 if the module left idle
+ * promptly, or 0 if the module did not leave idle before the timeout
+ * elapsed. XXX Deprecated - should be moved into drivers for the
+ * individual IP block that the IDLEST register exists in.
+ */
+static int _wait_idlest_generic(void __iomem *reg, u32 mask, u8 idlest,
+ const char *name)
+{
+ int i = 0, ena = 0;
+
+ ena = (idlest) ? 0 : mask;
+
+ omap_test_timeout(((__raw_readl(reg) & mask) == ena),
+ MAX_MODULE_ENABLE_WAIT, i);
+
+ if (i < MAX_MODULE_ENABLE_WAIT)
+ pr_debug("omap clock: module associated with clock %s ready after %d loops\n",
+ name, i);
+ else
+ pr_err("omap clock: module associated with clock %s didn't enable in %d tries\n",
+ name, MAX_MODULE_ENABLE_WAIT);
+
+ return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;
+};
+
/**
* _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
* @clk: struct clk * belonging to the module
@@ -71,7 +112,9 @@ static DEFINE_SPINLOCK(clockfw_lock);
static void _omap2_module_wait_ready(struct clk *clk)
{
void __iomem *companion_reg, *idlest_reg;
- u8 other_bit, idlest_bit, idlest_val;
+ u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
+ s16 prcm_mod;
+ int r;
/* Not all modules have multiple clocks that their IDLEST depends on */
if (clk->ops->find_companion) {
@@ -82,8 +125,14 @@ static void _omap2_module_wait_ready(struct clk *clk)
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
- omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
- __clk_get_name(clk));
+ r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id);
+ if (r) {
+ /* IDLEST register not in the CM module */
+ _wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val,
+ clk->name);
+ } else {
+ cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit);
+ };
}
/* Public functions */