فهرست منبع

Merge branch 'integration-2.6.39-for-tony' of git://git.pwsan.com/linux-integration into omap-for-linus

Conflicts:
	arch/arm/mach-omap2/pm34xx.c
Tony Lindgren 14 سال پیش
والد
کامیت
a2358a7bc3
75فایلهای تغییر یافته به همراه3503 افزوده شده و 1754 حذف شده
  1. 10 0
      MAINTAINERS
  2. 26 8
      arch/arm/mach-omap2/Makefile
  3. 24 0
      arch/arm/mach-omap2/clkt2xxx_apll.c
  4. 63 0
      arch/arm/mach-omap2/clkt2xxx_dpll.c
  5. 14 0
      arch/arm/mach-omap2/clkt2xxx_osc.c
  6. 23 68
      arch/arm/mach-omap2/clkt_dpll.c
  7. 82 0
      arch/arm/mach-omap2/clkt_iclk.c
  8. 19 9
      arch/arm/mach-omap2/clock.c
  9. 16 5
      arch/arm/mach-omap2/clock.h
  10. 122 99
      arch/arm/mach-omap2/clock2420_data.c
  11. 120 112
      arch/arm/mach-omap2/clock2430_data.c
  12. 2 2
      arch/arm/mach-omap2/clock2xxx.h
  13. 28 1
      arch/arm/mach-omap2/clock34xx.c
  14. 4 1
      arch/arm/mach-omap2/clock34xx.h
  15. 3 1
      arch/arm/mach-omap2/clock3517.c
  16. 0 3
      arch/arm/mach-omap2/clock3xxx.c
  17. 84 81
      arch/arm/mach-omap2/clock3xxx_data.c
  18. 34 23
      arch/arm/mach-omap2/clock44xx_data.c
  19. 6 0
      arch/arm/mach-omap2/clock_common_data.c
  20. 143 296
      arch/arm/mach-omap2/clockdomain.c
  21. 60 10
      arch/arm/mach-omap2/clockdomain.h
  22. 274 0
      arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
  23. 137 0
      arch/arm/mach-omap2/clockdomain44xx.c
  24. 10 2
      arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
  25. 388 8
      arch/arm/mach-omap2/clockdomains44xx_data.c
  26. 3 0
      arch/arm/mach-omap2/cm-regbits-24xx.h
  27. 69 0
      arch/arm/mach-omap2/cm2xxx_3xxx.c
  28. 8 0
      arch/arm/mach-omap2/cm2xxx_3xxx.h
  29. 1 0
      arch/arm/mach-omap2/cm44xx.h
  30. 21 0
      arch/arm/mach-omap2/cminst44xx.c
  31. 6 0
      arch/arm/mach-omap2/cminst44xx.h
  32. 2 2
      arch/arm/mach-omap2/cpuidle34xx.c
  33. 84 0
      arch/arm/mach-omap2/dpll44xx.c
  34. 3 3
      arch/arm/mach-omap2/io.c
  35. 119 38
      arch/arm/mach-omap2/omap_hwmod.c
  36. 6 5
      arch/arm/mach-omap2/omap_hwmod_2420_data.c
  37. 7 5
      arch/arm/mach-omap2/omap_hwmod_2430_data.c
  38. 13 34
      arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
  39. 24 0
      arch/arm/mach-omap2/omap_opp_data.h
  40. 1 1
      arch/arm/mach-omap2/omap_twl.c
  41. 65 1
      arch/arm/mach-omap2/opp3xxx_data.c
  42. 42 1
      arch/arm/mach-omap2/opp4xxx_data.c
  43. 4 4
      arch/arm/mach-omap2/pm.c
  44. 8 69
      arch/arm/mach-omap2/pm24xx.c
  45. 4 123
      arch/arm/mach-omap2/pm34xx.c
  46. 42 1
      arch/arm/mach-omap2/powerdomain.c
  47. 8 11
      arch/arm/mach-omap2/powerdomain.h
  48. 5 4
      arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
  49. 9 9
      arch/arm/mach-omap2/powerdomains2xxx_data.c
  50. 19 19
      arch/arm/mach-omap2/powerdomains3xxx_data.c
  51. 44 44
      arch/arm/mach-omap2/powerdomains44xx_data.c
  52. 2 2
      arch/arm/mach-omap2/prcm_mpu44xx.h
  53. 10 8
      arch/arm/mach-omap2/prm2xxx_3xxx.c
  54. 3 2
      arch/arm/mach-omap2/prm2xxx_3xxx.h
  55. 1 1
      arch/arm/mach-omap2/smartreflex-class3.c
  56. 1 1
      arch/arm/mach-omap2/smartreflex.c
  57. 2 1
      arch/arm/mach-omap2/smartreflex.h
  58. 2 2
      arch/arm/mach-omap2/sr_device.c
  59. 83 0
      arch/arm/mach-omap2/vc.h
  60. 63 0
      arch/arm/mach-omap2/vc3xxx_data.c
  61. 75 0
      arch/arm/mach-omap2/vc44xx_data.c
  62. 218 552
      arch/arm/mach-omap2/voltage.c
  63. 59 30
      arch/arm/mach-omap2/voltage.h
  64. 95 0
      arch/arm/mach-omap2/voltagedomains3xxx_data.c
  65. 102 0
      arch/arm/mach-omap2/voltagedomains44xx_data.c
  66. 143 0
      arch/arm/mach-omap2/vp.h
  67. 82 0
      arch/arm/mach-omap2/vp3xxx_data.c
  68. 100 0
      arch/arm/mach-omap2/vp44xx_data.c
  69. 71 28
      arch/arm/plat-omap/clock.c
  70. 4 0
      arch/arm/plat-omap/dmtimer.c
  71. 20 7
      arch/arm/plat-omap/include/plat/clock.h
  72. 6 2
      arch/arm/plat-omap/include/plat/omap_hwmod.h
  73. 26 10
      arch/arm/plat-omap/omap_device.c
  74. 3 3
      drivers/mmc/host/omap_hsmmc.c
  75. 23 2
      drivers/watchdog/omap_wdt.c

+ 10 - 0
MAINTAINERS

@@ -4506,6 +4506,16 @@ L:	linux-omap@vger.kernel.org
 S:	Maintained
 F:	arch/arm/*omap*/*pm*
 
+OMAP POWERDOMAIN/CLOCKDOMAIN SOC ADAPTATION LAYER SUPPORT
+M:	Rajendra Nayak <rnayak@ti.com>
+M:	Paul Walmsley <paul@pwsan.com>
+L:	linux-omap@vger.kernel.org
+S:	Maintained
+F:	arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
+F:	arch/arm/mach-omap2/powerdomain44xx.c
+F:	arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+F:	arch/arm/mach-omap2/clockdomain44xx.c
+
 OMAP AUDIO SUPPORT
 M:	Jarkko Nikula <jhnikula@gmail.com>
 L:	alsa-devel@alsa-project.org (subscribers-only)

+ 26 - 8
arch/arm/mach-omap2/Makefile

@@ -59,10 +59,10 @@ endif
 # Power Management
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
-obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o pm_bus.o voltage.o
-obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o voltage.o \
+obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o \
 					   cpuidle34xx.o pm_bus.o
-obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o voltage.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o pm_bus.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
 obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)	+= smartreflex-class3.o
@@ -78,13 +78,25 @@ endif
 
 # PRCM
 obj-$(CONFIG_ARCH_OMAP2)		+= prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3)		+= prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
+					   vc3xxx_data.o vp3xxx_data.o
 # XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
 # will be removed once the OMAP4 part of the codebase is converted to
 # use OMAP4-specific PRCM functions.
 obj-$(CONFIG_ARCH_OMAP4)		+= prcm.o cm2xxx_3xxx.o cminst44xx.o \
 					   cm44xx.o prcm_mpu44xx.o \
-					   prminst44xx.o
+					   prminst44xx.o vc44xx_data.o \
+					   vp44xx_data.o
+
+# OMAP voltage domains
+ifeq ($(CONFIG_PM),y)
+voltagedomain-common			:= voltage.o
+obj-$(CONFIG_ARCH_OMAP2)		+= $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP3)		+= $(voltagedomain-common) \
+					   voltagedomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(voltagedomain-common) \
+					   voltagedomains44xx_data.o
+endif
 
 # OMAP powerdomain framework
 powerdomain-common			+= powerdomain.o powerdomain-common.o
@@ -102,25 +114,31 @@ obj-$(CONFIG_ARCH_OMAP4)		+= $(powerdomain-common) \
 
 # PRCM clockdomain control
 obj-$(CONFIG_ARCH_OMAP2)		+= clockdomain.o \
+					   clockdomain2xxx_3xxx.o \
 					   clockdomains2xxx_3xxx_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clockdomain.o \
+					   clockdomain2xxx_3xxx.o \
 					   clockdomains2xxx_3xxx_data.o
 obj-$(CONFIG_ARCH_OMAP4)		+= clockdomain.o \
+					   clockdomain44xx.o \
 					   clockdomains44xx_data.o
+
 # Clock framework
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o \
 					   clkt2xxx_sys.o \
 					   clkt2xxx_dpllcore.o \
 					   clkt2xxx_virt_prcm_set.o \
-					   clkt2xxx_apll.o clkt2xxx_osc.o
+					   clkt2xxx_apll.o clkt2xxx_osc.o \
+					   clkt2xxx_dpll.o clkt_iclk.o
 obj-$(CONFIG_SOC_OMAP2420)		+= clock2420_data.o
 obj-$(CONFIG_SOC_OMAP2430)		+= clock2430.o clock2430_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(clock-common) clock3xxx.o \
 					   clock34xx.o clkt34xx_dpll3m2.o \
 					   clock3517.o clock36xx.o \
-					   dpll3xxx.o clock3xxx_data.o
+					   dpll3xxx.o clock3xxx_data.o \
+					   clkt_iclk.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common) clock44xx_data.o \
-					   dpll3xxx.o
+					   dpll3xxx.o dpll44xx.o
 
 # OMAP2 clock rate set data (old "OPP" data)
 obj-$(CONFIG_SOC_OMAP2420)		+= opp2420_data.o

+ 24 - 0
arch/arm/mach-omap2/clkt2xxx_apll.c

@@ -78,6 +78,26 @@ static int omap2_clk_apll54_enable(struct clk *clk)
 	return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);
 }
 
+static void _apll96_allow_idle(struct clk *clk)
+{
+	omap2xxx_cm_set_apll96_auto_low_power_stop();
+}
+
+static void _apll96_deny_idle(struct clk *clk)
+{
+	omap2xxx_cm_set_apll96_disable_autoidle();
+}
+
+static void _apll54_allow_idle(struct clk *clk)
+{
+	omap2xxx_cm_set_apll54_auto_low_power_stop();
+}
+
+static void _apll54_deny_idle(struct clk *clk)
+{
+	omap2xxx_cm_set_apll54_disable_autoidle();
+}
+
 /* Stop APLL */
 static void omap2_clk_apll_disable(struct clk *clk)
 {
@@ -93,11 +113,15 @@ static void omap2_clk_apll_disable(struct clk *clk)
 const struct clkops clkops_apll96 = {
 	.enable		= omap2_clk_apll96_enable,
 	.disable	= omap2_clk_apll_disable,
+	.allow_idle	= _apll96_allow_idle,
+	.deny_idle	= _apll96_deny_idle,
 };
 
 const struct clkops clkops_apll54 = {
 	.enable		= omap2_clk_apll54_enable,
 	.disable	= omap2_clk_apll_disable,
+	.allow_idle	= _apll54_allow_idle,
+	.deny_idle	= _apll54_deny_idle,
 };
 
 /* Public functions */

+ 63 - 0
arch/arm/mach-omap2/clkt2xxx_dpll.c

@@ -0,0 +1,63 @@
+/*
+ * OMAP2-specific DPLL control functions
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* Private functions */
+
+/**
+ * _allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control.  The DPLL will enter low-power
+ * stop when its downstream clocks are gated.  No return value.
+ * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
+ * instead.  Add some mechanism to optionally enter this mode.
+ */
+static void _allow_idle(struct clk *clk)
+{
+	if (!clk || !clk->dpll_data)
+		return;
+
+	omap2xxx_cm_set_dpll_auto_low_power_stop();
+}
+
+/**
+ * _deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control.  No return value.
+ */
+static void _deny_idle(struct clk *clk)
+{
+	if (!clk || !clk->dpll_data)
+		return;
+
+	omap2xxx_cm_set_dpll_disable_autoidle();
+}
+
+
+/* Public data */
+
+const struct clkops clkops_omap2xxx_dpll_ops = {
+	.allow_idle	= _allow_idle,
+	.deny_idle	= _deny_idle,
+};
+

+ 14 - 0
arch/arm/mach-omap2/clkt2xxx_osc.c

@@ -30,6 +30,13 @@
 #include "prm2xxx_3xxx.h"
 #include "prm-regbits-24xx.h"
 
+/*
+ * XXX This does not actually enable the osc_ck, since the osc_ck must
+ * be running for this function to be called.  Instead, this function
+ * is used to disable an autoidle mode on the osc_ck.  The existing
+ * clk_enable/clk_disable()-based usecounting for osc_ck should be
+ * replaced with autoidle-based usecounting.
+ */
 static int omap2_enable_osc_ck(struct clk *clk)
 {
 	u32 pcc;
@@ -41,6 +48,13 @@ static int omap2_enable_osc_ck(struct clk *clk)
 	return 0;
 }
 
+/*
+ * XXX This does not actually disable the osc_ck, since doing so would
+ * immediately halt the system.  Instead, this function is used to
+ * enable an autoidle mode on the osc_ck.  The existing
+ * clk_enable/clk_disable()-based usecounting for osc_ck should be
+ * replaced with autoidle-based usecounting.
+ */
 static void omap2_disable_osc_ck(struct clk *clk)
 {
 	u32 pcc;

+ 23 - 68
arch/arm/mach-omap2/clkt_dpll.c

@@ -178,12 +178,11 @@ void omap2_init_dpll_parent(struct clk *clk)
 	if (!dd)
 		return;
 
-	/* Return bypass rate if DPLL is bypassed */
 	v = __raw_readl(dd->control_reg);
 	v &= dd->enable_mask;
 	v >>= __ffs(dd->enable_mask);
 
-	/* Reparent in case the dpll is in bypass */
+	/* Reparent the struct clk in case the dpll is in bypass */
 	if (cpu_is_omap24xx()) {
 		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
 		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
@@ -259,51 +258,23 @@ u32 omap2_get_dpll_rate(struct clk *clk)
 
 /* DPLL rate rounding code */
 
-/**
- * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
- * @clk: struct clk * of the DPLL
- * @tolerance: maximum rate error tolerance
- *
- * Set the maximum DPLL rate error tolerance for the rate rounding
- * algorithm.  The rate tolerance is an attempt to balance DPLL power
- * saving (the least divider value "n") vs. rate fidelity (the least
- * difference between the desired DPLL target rate and the rounded
- * rate out of the algorithm).  So, increasing the tolerance is likely
- * to decrease DPLL power consumption and increase DPLL rate error.
- * Returns -EINVAL if provided a null clock ptr or a clk that is not a
- * DPLL; or 0 upon success.
- */
-int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
-{
-	if (!clk || !clk->dpll_data)
-		return -EINVAL;
-
-	clk->dpll_data->rate_tolerance = tolerance;
-
-	return 0;
-}
-
 /**
  * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
  * @clk: struct clk * for a DPLL
  * @target_rate: desired DPLL clock rate
  *
- * Given a DPLL, a desired target rate, and a rate tolerance, round
- * the target rate to a possible, programmable rate for this DPLL.
- * Rate tolerance is assumed to be set by the caller before this
- * function is called.  Attempts to select the minimum possible n
- * within the tolerance to reduce power consumption.  Stores the
- * computed (m, n) in the DPLL's dpll_data structure so set_rate()
- * will not need to call this (expensive) function again.  Returns ~0
- * if the target rate cannot be rounded, either because the rate is
- * too low or because the rate tolerance is set too tightly; or the
- * rounded rate upon success.
+ * Given a DPLL and a desired target rate, round the target rate to a
+ * possible, programmable rate for this DPLL.  Attempts to select the
+ * minimum possible n.  Stores the computed (m, n) in the DPLL's
+ * dpll_data structure so set_rate() will not need to call this
+ * (expensive) function again.  Returns ~0 if the target rate cannot
+ * be rounded, or the rounded rate upon success.
  */
 long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
 {
-	int m, n, r, e, scaled_max_m;
-	unsigned long scaled_rt_rp, new_rate;
-	int min_e = -1, min_e_m = -1, min_e_n = -1;
+	int m, n, r, scaled_max_m;
+	unsigned long scaled_rt_rp;
+	unsigned long new_rate = 0;
 	struct dpll_data *dd;
 
 	if (!clk || !clk->dpll_data)
@@ -311,8 +282,8 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
 
 	dd = clk->dpll_data;
 
-	pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
-		 "%ld\n", clk->name, target_rate);
+	pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
+		 clk->name, target_rate);
 
 	scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
 	scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
@@ -347,39 +318,23 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
 		if (r == DPLL_MULT_UNDERFLOW)
 			continue;
 
-		e = target_rate - new_rate;
-		pr_debug("clock: n = %d: m = %d: rate error is %d "
-			 "(new_rate = %ld)\n", n, m, e, new_rate);
-
-		if (min_e == -1 ||
-		    min_e >= (int)(abs(e) - dd->rate_tolerance)) {
-			min_e = e;
-			min_e_m = m;
-			min_e_n = n;
-
-			pr_debug("clock: found new least error %d\n", min_e);
+		pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",
+			 clk->name, m, n, new_rate);
 
-			/* We found good settings -- bail out now */
-			if (min_e <= dd->rate_tolerance)
-				break;
+		if (target_rate == new_rate) {
+			dd->last_rounded_m = m;
+			dd->last_rounded_n = n;
+			dd->last_rounded_rate = target_rate;
+			break;
 		}
 	}
 
-	if (min_e < 0) {
-		pr_debug("clock: error: target rate or tolerance too low\n");
+	if (target_rate != new_rate) {
+		pr_debug("clock: %s: cannot round to rate %ld\n", clk->name,
+			 target_rate);
 		return ~0;
 	}
 
-	dd->last_rounded_m = min_e_m;
-	dd->last_rounded_n = min_e_n;
-	dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
-						       min_e_m,  min_e_n);
-
-	pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
-		 min_e, min_e_m, min_e_n);
-	pr_debug("clock: final rate: %ld  (target rate: %ld)\n",
-		 dd->last_rounded_rate, target_rate);
-
-	return dd->last_rounded_rate;
+	return target_rate;
 }
 

+ 82 - 0
arch/arm/mach-omap2/clkt_iclk.c

@@ -0,0 +1,82 @@
+/*
+ * OMAP2/3 interface clock control
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* Private functions */
+
+/* XXX */
+void omap2_clkt_iclk_allow_idle(struct clk *clk)
+{
+	u32 v, r;
+
+	r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+	v = __raw_readl((__force void __iomem *)r);
+	v |= (1 << clk->enable_bit);
+	__raw_writel(v, (__force void __iomem *)r);
+}
+
+/* XXX */
+void omap2_clkt_iclk_deny_idle(struct clk *clk)
+{
+	u32 v, r;
+
+	r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+	v = __raw_readl((__force void __iomem *)r);
+	v &= ~(1 << clk->enable_bit);
+	__raw_writel(v, (__force void __iomem *)r);
+}
+
+/* Public data */
+
+const struct clkops clkops_omap2_iclk_dflt_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_companion	= omap2_clk_dflt_find_companion,
+	.find_idlest	= omap2_clk_dflt_find_idlest,
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_iclk_dflt = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_iclk_idle_only = {
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_mdmclk_dflt_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_companion	= omap2_clk_dflt_find_companion,
+	.find_idlest	= omap2_clk_dflt_find_idlest,
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};
+

+ 19 - 9
arch/arm/mach-omap2/clock.c

@@ -261,10 +261,11 @@ void omap2_clk_disable(struct clk *clk)
 
 	pr_debug("clock: %s: disabling in hardware\n", clk->name);
 
-	clk->ops->disable(clk);
+	if (clk->ops && clk->ops->disable)
+		clk->ops->disable(clk);
 
 	if (clk->clkdm)
-		omap2_clkdm_clk_disable(clk->clkdm, clk);
+		clkdm_clk_disable(clk->clkdm, clk);
 
 	if (clk->parent)
 		omap2_clk_disable(clk->parent);
@@ -304,7 +305,7 @@ int omap2_clk_enable(struct clk *clk)
 	}
 
 	if (clk->clkdm) {
-		ret = omap2_clkdm_clk_enable(clk->clkdm, clk);
+		ret = clkdm_clk_enable(clk->clkdm, clk);
 		if (ret) {
 			WARN(1, "clock: %s: could not enable clockdomain %s: "
 			     "%d\n", clk->name, clk->clkdm->name, ret);
@@ -312,17 +313,20 @@ int omap2_clk_enable(struct clk *clk)
 		}
 	}
 
-	ret = clk->ops->enable(clk);
-	if (ret) {
-		WARN(1, "clock: %s: could not enable: %d\n", clk->name, ret);
-		goto oce_err3;
+	if (clk->ops && clk->ops->enable) {
+		ret = clk->ops->enable(clk);
+		if (ret) {
+			WARN(1, "clock: %s: could not enable: %d\n",
+			     clk->name, ret);
+			goto oce_err3;
+		}
 	}
 
 	return 0;
 
 oce_err3:
 	if (clk->clkdm)
-		omap2_clkdm_clk_disable(clk->clkdm, clk);
+		clkdm_clk_disable(clk->clkdm, clk);
 oce_err2:
 	if (clk->parent)
 		omap2_clk_disable(clk->parent);
@@ -373,10 +377,16 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 const struct clkops clkops_omap3_noncore_dpll_ops = {
 	.enable		= omap3_noncore_dpll_enable,
 	.disable	= omap3_noncore_dpll_disable,
+	.allow_idle	= omap3_dpll_allow_idle,
+	.deny_idle	= omap3_dpll_deny_idle,
 };
 
-#endif
+const struct clkops clkops_omap3_core_dpll_ops = {
+	.allow_idle	= omap3_dpll_allow_idle,
+	.deny_idle	= omap3_dpll_deny_idle,
+};
 
+#endif
 
 /*
  * OMAP2+ clock reset and init functions

+ 16 - 5
arch/arm/mach-omap2/clock.h

@@ -2,7 +2,7 @@
  *  linux/arch/arm/mach-omap2/clock.h
  *
  *  Copyright (C) 2005-2009 Texas Instruments, Inc.
- *  Copyright (C) 2004-2009 Nokia Corporation
+ *  Copyright (C) 2004-2011 Nokia Corporation
  *
  *  Contacts:
  *  Richard Woodruff <r-woodruff2@ti.com>
@@ -18,9 +18,6 @@
 
 #include <plat/clock.h>
 
-/* The maximum error between a target DPLL rate and the rounded rate in Hz */
-#define DEFAULT_DPLL_RATE_TOLERANCE	50000
-
 /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
 #define CORE_CLK_SRC_32K		0x0
 #define CORE_CLK_SRC_DPLL		0x1
@@ -55,7 +52,6 @@ void omap2_clk_disable(struct clk *clk);
 long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
 int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
-int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
 long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
 unsigned long omap3_dpll_recalc(struct clk *clk);
 unsigned long omap3_clkoutx2_recalc(struct clk *clk);
@@ -65,6 +61,9 @@ u32 omap3_dpll_autoidle_read(struct clk *clk);
 int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
 int omap3_noncore_dpll_enable(struct clk *clk);
 void omap3_noncore_dpll_disable(struct clk *clk);
+int omap4_dpllmx_gatectrl_read(struct clk *clk);
+void omap4_dpllmx_allow_gatectrl(struct clk *clk);
+void omap4_dpllmx_deny_gatectrl(struct clk *clk);
 
 #ifdef CONFIG_OMAP_RESET_CLOCKS
 void omap2_clk_disable_unused(struct clk *clk);
@@ -83,6 +82,10 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
 int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
 int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
 
+/* clkt_iclk.c public functions */
+extern void omap2_clkt_iclk_allow_idle(struct clk *clk);
+extern void omap2_clkt_iclk_deny_idle(struct clk *clk);
+
 u32 omap2_get_dpll_rate(struct clk *clk);
 void omap2_init_dpll_parent(struct clk *clk);
 
@@ -136,6 +139,7 @@ extern struct clk *vclk, *sclk;
 extern const struct clksel_rate gpt_32k_rates[];
 extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
+extern const struct clksel_rate dsp_ick_rates[];
 
 #if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
 extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
@@ -145,6 +149,13 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
 #define omap2_clk_exit_cpufreq_table	0
 #endif
 
+extern const struct clkops clkops_omap2_iclk_dflt_wait;
+extern const struct clkops clkops_omap2_iclk_dflt;
+extern const struct clkops clkops_omap2_iclk_idle_only;
+extern const struct clkops clkops_omap2_mdmclk_dflt_wait;
+extern const struct clkops clkops_omap2xxx_dpll_ops;
 extern const struct clkops clkops_omap3_noncore_dpll_ops;
+extern const struct clkops clkops_omap3_core_dpll_ops;
+extern const struct clkops clkops_omap4_dpllmx_ops;
 
 #endif

+ 122 - 99
arch/arm/mach-omap2/clock2420_data.c

@@ -1,12 +1,12 @@
 /*
- *  linux/arch/arm/mach-omap2/clock2420_data.c
+ * OMAP2420 clock data
  *
- *  Copyright (C) 2005-2009 Texas Instruments, Inc.
- *  Copyright (C) 2004-2010 Nokia Corporation
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
  *
- *  Contacts:
- *  Richard Woodruff <r-woodruff2@ti.com>
- *  Paul Walmsley
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -34,18 +34,15 @@
 /*
  * 2420 clock tree.
  *
- * NOTE:In many cases here we are assigning a 'default' parent.	In many
- *	cases the parent is selectable.	The get/set parent calls will also
- *	switch sources.
- *
- *	Many some clocks say always_enabled, but they can be auto idled for
- *	power savings. They will always be available upon clock request.
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ *	many cases the parent is selectable. The set parent calls will
+ *	also switch sources.
  *
  *	Several sources are given initial rates which may be wrong, this will
  *	be fixed up in the init func.
  *
  *	Things are broadly separated below by clock domains. It is
- *	noteworthy that most periferals have dependencies on multiple clock
+ *	noteworthy that most peripherals have dependencies on multiple clock
  *	domains. Many get their interface clocks from the L4 domain, but get
  *	functional clocks from fixed sources or other core domain derived
  *	clocks.
@@ -55,7 +52,7 @@
 static struct clk func_32k_ck = {
 	.name		= "func_32k_ck",
 	.ops		= &clkops_null,
-	.rate		= 32000,
+	.rate		= 32768,
 	.clkdm_name	= "wkup_clkdm",
 };
 
@@ -116,7 +113,6 @@ static struct dpll_data dpll_dd = {
 	.max_multiplier		= 1023,
 	.min_divider		= 1,
 	.max_divider		= 16,
-	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 /*
@@ -125,7 +121,7 @@ static struct dpll_data dpll_dd = {
  */
 static struct clk dpll_ck = {
 	.name		= "dpll_ck",
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap2xxx_dpll_ops,
 	.parent		= &sys_ck,		/* Can be func_32k also */
 	.dpll_data	= &dpll_dd,
 	.clkdm_name	= "wkup_clkdm",
@@ -455,36 +451,22 @@ static struct clk dsp_fck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
-/* DSP interface clock */
-static const struct clksel_rate dsp_irate_ick_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_irate_ick_clksel[] = {
-	{ .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
+static const struct clksel dsp_ick_clksel[] = {
+	{ .parent = &dsp_fck, .rates = dsp_ick_rates },
 	{ .parent = NULL }
 };
 
-/* This clock does not exist as such in the TRM. */
-static struct clk dsp_irate_ick = {
-	.name		= "dsp_irate_ick",
-	.ops		= &clkops_null,
-	.parent		= &dsp_fck,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
-	.clksel		= dsp_irate_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* 2420 only */
 static struct clk dsp_ick = {
 	.name		= "dsp_ick",	 /* apparently ipi and isp */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dsp_irate_ick,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &dsp_fck,
+	.clkdm_name	= "dsp_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP2420_EN_DSP_IPI_SHIFT,	      /* for ipi */
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
+	.clksel		= dsp_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
 };
 
 /*
@@ -579,7 +561,7 @@ static const struct clksel usb_l4_ick_clksel[] = {
 /* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
 static struct clk usb_l4_ick = {	/* FS-USB interface clock */
 	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l3_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -661,7 +643,7 @@ static struct clk ssi_ssr_sst_fck = {
  */
 static struct clk ssi_l4_ick = {
 	.name		= "ssi_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -716,6 +698,7 @@ static struct clk gfx_2d_fck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
+/* This interface clock does not have a CM_AUTOIDLE bit */
 static struct clk gfx_ick = {
 	.name		= "gfx_ick",		/* From l3 */
 	.ops		= &clkops_omap2_dflt_wait,
@@ -763,7 +746,7 @@ static const struct clksel dss1_fck_clksel[] = {
 
 static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
 	.name		= "dss_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &l4_ck,	/* really both l3 and l4 */
 	.clkdm_name	= "dss_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -825,6 +808,14 @@ static struct clk dss_54m_fck = {	/* Alt clk used in power management */
 	.recalc		= &followparent_recalc,
 };
 
+static struct clk wu_l4_ick = {
+	.name		= "wu_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
 /*
  * CORE power domain ICLK & FCLK defines.
  * Many of the these can have more than one possible parent. Entries
@@ -845,9 +836,9 @@ static const struct clksel omap24xx_gpt_clksel[] = {
 
 static struct clk gpt1_ick = {
 	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -871,7 +862,7 @@ static struct clk gpt1_fck = {
 
 static struct clk gpt2_ick = {
 	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -895,7 +886,7 @@ static struct clk gpt2_fck = {
 
 static struct clk gpt3_ick = {
 	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -919,7 +910,7 @@ static struct clk gpt3_fck = {
 
 static struct clk gpt4_ick = {
 	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -943,7 +934,7 @@ static struct clk gpt4_fck = {
 
 static struct clk gpt5_ick = {
 	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -967,7 +958,7 @@ static struct clk gpt5_fck = {
 
 static struct clk gpt6_ick = {
 	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -991,8 +982,9 @@ static struct clk gpt6_fck = {
 
 static struct clk gpt7_ick = {
 	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1014,7 +1006,7 @@ static struct clk gpt7_fck = {
 
 static struct clk gpt8_ick = {
 	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1038,7 +1030,7 @@ static struct clk gpt8_fck = {
 
 static struct clk gpt9_ick = {
 	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1062,7 +1054,7 @@ static struct clk gpt9_fck = {
 
 static struct clk gpt10_ick = {
 	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1086,7 +1078,7 @@ static struct clk gpt10_fck = {
 
 static struct clk gpt11_ick = {
 	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1110,7 +1102,7 @@ static struct clk gpt11_fck = {
 
 static struct clk gpt12_ick = {
 	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1134,7 +1126,7 @@ static struct clk gpt12_fck = {
 
 static struct clk mcbsp1_ick = {
 	.name		= "mcbsp1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1174,7 +1166,7 @@ static struct clk mcbsp1_fck = {
 
 static struct clk mcbsp2_ick = {
 	.name		= "mcbsp2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1198,7 +1190,7 @@ static struct clk mcbsp2_fck = {
 
 static struct clk mcspi1_ick = {
 	.name		= "mcspi1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1218,7 +1210,7 @@ static struct clk mcspi1_fck = {
 
 static struct clk mcspi2_ick = {
 	.name		= "mcspi2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1238,7 +1230,7 @@ static struct clk mcspi2_fck = {
 
 static struct clk uart1_ick = {
 	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1258,7 +1250,7 @@ static struct clk uart1_fck = {
 
 static struct clk uart2_ick = {
 	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1278,7 +1270,7 @@ static struct clk uart2_fck = {
 
 static struct clk uart3_ick = {
 	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1298,9 +1290,9 @@ static struct clk uart3_fck = {
 
 static struct clk gpios_ick = {
 	.name		= "gpios_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1318,9 +1310,9 @@ static struct clk gpios_fck = {
 
 static struct clk mpu_wdt_ick = {
 	.name		= "mpu_wdt_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1338,10 +1330,10 @@ static struct clk mpu_wdt_fck = {
 
 static struct clk sync_32k_ick = {
 	.name		= "sync_32k_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1349,9 +1341,9 @@ static struct clk sync_32k_ick = {
 
 static struct clk wdt1_ick = {
 	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1359,10 +1351,10 @@ static struct clk wdt1_ick = {
 
 static struct clk omapctrl_ick = {
 	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1370,7 +1362,7 @@ static struct clk omapctrl_ick = {
 
 static struct clk cam_ick = {
 	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1395,7 +1387,7 @@ static struct clk cam_fck = {
 
 static struct clk mailboxes_ick = {
 	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1405,7 +1397,7 @@ static struct clk mailboxes_ick = {
 
 static struct clk wdt4_ick = {
 	.name		= "wdt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1425,7 +1417,7 @@ static struct clk wdt4_fck = {
 
 static struct clk wdt3_ick = {
 	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1445,7 +1437,7 @@ static struct clk wdt3_fck = {
 
 static struct clk mspro_ick = {
 	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1465,7 +1457,7 @@ static struct clk mspro_fck = {
 
 static struct clk mmc_ick = {
 	.name		= "mmc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1485,7 +1477,7 @@ static struct clk mmc_fck = {
 
 static struct clk fac_ick = {
 	.name		= "fac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1505,7 +1497,7 @@ static struct clk fac_fck = {
 
 static struct clk eac_ick = {
 	.name		= "eac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1525,7 +1517,7 @@ static struct clk eac_fck = {
 
 static struct clk hdq_ick = {
 	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1545,7 +1537,7 @@ static struct clk hdq_fck = {
 
 static struct clk i2c2_ick = {
 	.name		= "i2c2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1565,7 +1557,7 @@ static struct clk i2c2_fck = {
 
 static struct clk i2c1_ick = {
 	.name		= "i2c1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1583,12 +1575,18 @@ static struct clk i2c1_fck = {
 	.recalc		= &followparent_recalc,
 };
 
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
 static struct clk gpmc_fck = {
 	.name		= "gpmc_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
+	.ops		= &clkops_omap2_iclk_idle_only,
 	.parent		= &core_l3_ck,
 	.flags		= ENABLE_ON_INIT,
 	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_GPMC_SHIFT,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1600,17 +1598,38 @@ static struct clk sdma_fck = {
 	.recalc		= &followparent_recalc,
 };
 
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
 static struct clk sdma_ick = {
 	.name		= "sdma_ick",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &l4_ck,
+	.ops		= &clkops_omap2_iclk_idle_only,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_SDMA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
+static struct clk sdrc_ick = {
+	.name		= "sdrc_ick",
+	.ops		= &clkops_omap2_iclk_idle_only,
+	.parent		= &core_l3_ck,
+	.flags		= ENABLE_ON_INIT,
 	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_SDRC_SHIFT,
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk vlynq_ick = {
 	.name		= "vlynq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l3_ck,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1659,7 +1678,7 @@ static struct clk vlynq_fck = {
 
 static struct clk des_ick = {
 	.name		= "des_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1669,7 +1688,7 @@ static struct clk des_ick = {
 
 static struct clk sha_ick = {
 	.name		= "sha_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1679,7 +1698,7 @@ static struct clk sha_ick = {
 
 static struct clk rng_ick = {
 	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1689,7 +1708,7 @@ static struct clk rng_ick = {
 
 static struct clk aes_ick = {
 	.name		= "aes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1699,7 +1718,7 @@ static struct clk aes_ick = {
 
 static struct clk pka_ick = {
 	.name		= "pka_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1777,7 +1796,6 @@ static struct omap_clk omap2420_clks[] = {
 	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_242X),
 	/* dsp domain clocks */
 	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_242X),
-	CLK(NULL,	"dsp_irate_ick", &dsp_irate_ick, CK_242X),
 	CLK(NULL,	"dsp_ick",	&dsp_ick,	CK_242X),
 	CLK(NULL,	"iva1_ifck",	&iva1_ifck,	CK_242X),
 	CLK(NULL,	"iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
@@ -1797,6 +1815,7 @@ static struct omap_clk omap2420_clks[] = {
 	/* L4 domain clocks */
 	CLK(NULL,	"l4_ck",	&l4_ck,		CK_242X),
 	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_242X),
+	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_242X),
 	/* virtual meta-group clock */
 	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_242X),
 	/* general l4 interface ck, multi-parent functional clk */
@@ -1869,6 +1888,7 @@ static struct omap_clk omap2420_clks[] = {
 	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_242X),
 	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_242X),
 	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_242X),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_242X),
 	CLK(NULL,	"vlynq_ick",	&vlynq_ick,	CK_242X),
 	CLK(NULL,	"vlynq_fck",	&vlynq_fck,	CK_242X),
 	CLK(NULL,	"des_ick",	&des_ick,	CK_242X),
@@ -1913,6 +1933,9 @@ int __init omap2420_clk_init(void)
 		omap2_init_clk_clkdm(c->lk.clk);
 	}
 
+	/* Disable autoidle on all clocks; let the PM code enable it later */
+	omap_clk_disable_autoidle_all();
+
 	/* Check the MPU rate set by bootloader */
 	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
 	for (prcm = rate_table; prcm->mpu_speed; prcm++) {

+ 120 - 112
arch/arm/mach-omap2/clock2430_data.c

@@ -1,12 +1,12 @@
 /*
- *  linux/arch/arm/mach-omap2/clock2430_data.c
+ * OMAP2430 clock data
  *
- *  Copyright (C) 2005-2009 Texas Instruments, Inc.
- *  Copyright (C) 2004-2010 Nokia Corporation
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
  *
- *  Contacts:
- *  Richard Woodruff <r-woodruff2@ti.com>
- *  Paul Walmsley
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -34,18 +34,15 @@
 /*
  * 2430 clock tree.
  *
- * NOTE:In many cases here we are assigning a 'default' parent.	In many
- *	cases the parent is selectable.	The get/set parent calls will also
- *	switch sources.
- *
- *	Many some clocks say always_enabled, but they can be auto idled for
- *	power savings. They will always be available upon clock request.
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ *	many cases the parent is selectable. The set parent calls will
+ *	also switch sources.
  *
  *	Several sources are given initial rates which may be wrong, this will
  *	be fixed up in the init func.
  *
  *	Things are broadly separated below by clock domains. It is
- *	noteworthy that most periferals have dependencies on multiple clock
+ *	noteworthy that most peripherals have dependencies on multiple clock
  *	domains. Many get their interface clocks from the L4 domain, but get
  *	functional clocks from fixed sources or other core domain derived
  *	clocks.
@@ -55,7 +52,7 @@
 static struct clk func_32k_ck = {
 	.name		= "func_32k_ck",
 	.ops		= &clkops_null,
-	.rate		= 32000,
+	.rate		= 32768,
 	.clkdm_name	= "wkup_clkdm",
 };
 
@@ -116,7 +113,6 @@ static struct dpll_data dpll_dd = {
 	.max_multiplier		= 1023,
 	.min_divider		= 1,
 	.max_divider		= 16,
-	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 /*
@@ -125,7 +121,7 @@ static struct dpll_data dpll_dd = {
  */
 static struct clk dpll_ck = {
 	.name		= "dpll_ck",
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap2xxx_dpll_ops,
 	.parent		= &sys_ck,		/* Can be func_32k also */
 	.dpll_data	= &dpll_dd,
 	.clkdm_name	= "wkup_clkdm",
@@ -434,37 +430,23 @@ static struct clk dsp_fck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
-/* DSP interface clock */
-static const struct clksel_rate dsp_irate_ick_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_243X },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_irate_ick_clksel[] = {
-	{ .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
+static const struct clksel dsp_ick_clksel[] = {
+	{ .parent = &dsp_fck, .rates = dsp_ick_rates },
 	{ .parent = NULL }
 };
 
-/* This clock does not exist as such in the TRM. */
-static struct clk dsp_irate_ick = {
-	.name		= "dsp_irate_ick",
-	.ops		= &clkops_null,
-	.parent		= &dsp_fck,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
-	.clksel		= dsp_irate_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
 /* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
 static struct clk iva2_1_ick = {
 	.name		= "iva2_1_ick",
 	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dsp_irate_ick,
+	.parent		= &dsp_fck,
+	.clkdm_name	= "dsp_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
+	.clksel		= dsp_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
 };
 
 /*
@@ -525,7 +507,7 @@ static const struct clksel usb_l4_ick_clksel[] = {
 /* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
 static struct clk usb_l4_ick = {	/* FS-USB interface clock */
 	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l3_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -606,7 +588,7 @@ static struct clk ssi_ssr_sst_fck = {
  */
 static struct clk ssi_l4_ick = {
 	.name		= "ssi_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -661,6 +643,7 @@ static struct clk gfx_2d_fck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
+/* This interface clock does not have a CM_AUTOIDLE bit */
 static struct clk gfx_ick = {
 	.name		= "gfx_ick",		/* From l3 */
 	.ops		= &clkops_omap2_dflt_wait,
@@ -693,7 +676,7 @@ static const struct clksel mdm_ick_clksel[] = {
 
 static struct clk mdm_ick = {		/* used both as a ick and fck */
 	.name		= "mdm_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_ck,
 	.clkdm_name	= "mdm_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
@@ -706,7 +689,7 @@ static struct clk mdm_ick = {		/* used both as a ick and fck */
 
 static struct clk mdm_osc_ck = {
 	.name		= "mdm_osc_ck",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_mdmclk_dflt_wait,
 	.parent		= &osc_ck,
 	.clkdm_name	= "mdm_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
@@ -751,7 +734,7 @@ static const struct clksel dss1_fck_clksel[] = {
 
 static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
 	.name		= "dss_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &l4_ck,	/* really both l3 and l4 */
 	.clkdm_name	= "dss_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -813,6 +796,14 @@ static struct clk dss_54m_fck = {	/* Alt clk used in power management */
 	.recalc		= &followparent_recalc,
 };
 
+static struct clk wu_l4_ick = {
+	.name		= "wu_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
 /*
  * CORE power domain ICLK & FCLK defines.
  * Many of the these can have more than one possible parent. Entries
@@ -833,9 +824,9 @@ static const struct clksel omap24xx_gpt_clksel[] = {
 
 static struct clk gpt1_ick = {
 	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -859,7 +850,7 @@ static struct clk gpt1_fck = {
 
 static struct clk gpt2_ick = {
 	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -883,7 +874,7 @@ static struct clk gpt2_fck = {
 
 static struct clk gpt3_ick = {
 	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -907,7 +898,7 @@ static struct clk gpt3_fck = {
 
 static struct clk gpt4_ick = {
 	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -931,7 +922,7 @@ static struct clk gpt4_fck = {
 
 static struct clk gpt5_ick = {
 	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -955,7 +946,7 @@ static struct clk gpt5_fck = {
 
 static struct clk gpt6_ick = {
 	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -979,8 +970,9 @@ static struct clk gpt6_fck = {
 
 static struct clk gpt7_ick = {
 	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1002,7 +994,7 @@ static struct clk gpt7_fck = {
 
 static struct clk gpt8_ick = {
 	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1026,7 +1018,7 @@ static struct clk gpt8_fck = {
 
 static struct clk gpt9_ick = {
 	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1050,7 +1042,7 @@ static struct clk gpt9_fck = {
 
 static struct clk gpt10_ick = {
 	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1074,7 +1066,7 @@ static struct clk gpt10_fck = {
 
 static struct clk gpt11_ick = {
 	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1098,7 +1090,7 @@ static struct clk gpt11_fck = {
 
 static struct clk gpt12_ick = {
 	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1122,7 +1114,7 @@ static struct clk gpt12_fck = {
 
 static struct clk mcbsp1_ick = {
 	.name		= "mcbsp1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1162,7 +1154,7 @@ static struct clk mcbsp1_fck = {
 
 static struct clk mcbsp2_ick = {
 	.name		= "mcbsp2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1186,7 +1178,7 @@ static struct clk mcbsp2_fck = {
 
 static struct clk mcbsp3_ick = {
 	.name		= "mcbsp3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1210,7 +1202,7 @@ static struct clk mcbsp3_fck = {
 
 static struct clk mcbsp4_ick = {
 	.name		= "mcbsp4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1234,7 +1226,7 @@ static struct clk mcbsp4_fck = {
 
 static struct clk mcbsp5_ick = {
 	.name		= "mcbsp5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1258,7 +1250,7 @@ static struct clk mcbsp5_fck = {
 
 static struct clk mcspi1_ick = {
 	.name		= "mcspi1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1278,7 +1270,7 @@ static struct clk mcspi1_fck = {
 
 static struct clk mcspi2_ick = {
 	.name		= "mcspi2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1298,7 +1290,7 @@ static struct clk mcspi2_fck = {
 
 static struct clk mcspi3_ick = {
 	.name		= "mcspi3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1318,7 +1310,7 @@ static struct clk mcspi3_fck = {
 
 static struct clk uart1_ick = {
 	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1338,7 +1330,7 @@ static struct clk uart1_fck = {
 
 static struct clk uart2_ick = {
 	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1358,7 +1350,7 @@ static struct clk uart2_fck = {
 
 static struct clk uart3_ick = {
 	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1378,9 +1370,9 @@ static struct clk uart3_fck = {
 
 static struct clk gpios_ick = {
 	.name		= "gpios_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1398,9 +1390,9 @@ static struct clk gpios_fck = {
 
 static struct clk mpu_wdt_ick = {
 	.name		= "mpu_wdt_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1418,10 +1410,10 @@ static struct clk mpu_wdt_fck = {
 
 static struct clk sync_32k_ick = {
 	.name		= "sync_32k_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1429,9 +1421,9 @@ static struct clk sync_32k_ick = {
 
 static struct clk wdt1_ick = {
 	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1439,10 +1431,10 @@ static struct clk wdt1_ick = {
 
 static struct clk omapctrl_ick = {
 	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1450,9 +1442,9 @@ static struct clk omapctrl_ick = {
 
 static struct clk icr_ick = {
 	.name		= "icr_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.ops		= &clkops_omap2_iclk_dflt_wait,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1460,7 +1452,7 @@ static struct clk icr_ick = {
 
 static struct clk cam_ick = {
 	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1485,7 +1477,7 @@ static struct clk cam_fck = {
 
 static struct clk mailboxes_ick = {
 	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1495,7 +1487,7 @@ static struct clk mailboxes_ick = {
 
 static struct clk wdt4_ick = {
 	.name		= "wdt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1515,7 +1507,7 @@ static struct clk wdt4_fck = {
 
 static struct clk mspro_ick = {
 	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1535,7 +1527,7 @@ static struct clk mspro_fck = {
 
 static struct clk fac_ick = {
 	.name		= "fac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1555,7 +1547,7 @@ static struct clk fac_fck = {
 
 static struct clk hdq_ick = {
 	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1579,7 +1571,7 @@ static struct clk hdq_fck = {
  */
 static struct clk i2c2_ick = {
 	.name		= "i2c2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1603,7 +1595,7 @@ static struct clk i2chs2_fck = {
  */
 static struct clk i2c1_ick = {
 	.name		= "i2c1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1621,12 +1613,18 @@ static struct clk i2chs1_fck = {
 	.recalc		= &followparent_recalc,
 };
 
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
 static struct clk gpmc_fck = {
 	.name		= "gpmc_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
+	.ops		= &clkops_omap2_iclk_idle_only,
 	.parent		= &core_l3_ck,
 	.flags		= ENABLE_ON_INIT,
 	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_GPMC_SHIFT,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1638,20 +1636,26 @@ static struct clk sdma_fck = {
 	.recalc		= &followparent_recalc,
 };
 
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
 static struct clk sdma_ick = {
 	.name		= "sdma_ick",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &l4_ck,
+	.ops		= &clkops_omap2_iclk_idle_only,
+	.parent		= &core_l3_ck,
 	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_SDMA_SHIFT,
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk sdrc_ick = {
 	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
+	.ops		= &clkops_omap2_iclk_idle_only,
+	.parent		= &core_l3_ck,
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
+	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
 	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1659,7 +1663,7 @@ static struct clk sdrc_ick = {
 
 static struct clk des_ick = {
 	.name		= "des_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1669,7 +1673,7 @@ static struct clk des_ick = {
 
 static struct clk sha_ick = {
 	.name		= "sha_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1679,7 +1683,7 @@ static struct clk sha_ick = {
 
 static struct clk rng_ick = {
 	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1689,7 +1693,7 @@ static struct clk rng_ick = {
 
 static struct clk aes_ick = {
 	.name		= "aes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1699,7 +1703,7 @@ static struct clk aes_ick = {
 
 static struct clk pka_ick = {
 	.name		= "pka_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
@@ -1719,7 +1723,7 @@ static struct clk usb_fck = {
 
 static struct clk usbhs_ick = {
 	.name		= "usbhs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l3_ck,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1729,7 +1733,7 @@ static struct clk usbhs_ick = {
 
 static struct clk mmchs1_ick = {
 	.name		= "mmchs1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1741,7 +1745,7 @@ static struct clk mmchs1_fck = {
 	.name		= "mmchs1_fck",
 	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
+	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1749,7 +1753,7 @@ static struct clk mmchs1_fck = {
 
 static struct clk mmchs2_ick = {
 	.name		= "mmchs2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1761,6 +1765,7 @@ static struct clk mmchs2_fck = {
 	.name		= "mmchs2_fck",
 	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1768,7 +1773,7 @@ static struct clk mmchs2_fck = {
 
 static struct clk gpio5_ick = {
 	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1788,7 +1793,7 @@ static struct clk gpio5_fck = {
 
 static struct clk mdm_intc_ick = {
 	.name		= "mdm_intc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1880,7 +1885,6 @@ static struct omap_clk omap2430_clks[] = {
 	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_243X),
 	/* dsp domain clocks */
 	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_243X),
-	CLK(NULL,	"dsp_irate_ick", &dsp_irate_ick, CK_243X),
 	CLK(NULL,	"iva2_1_ick",	&iva2_1_ick,	CK_243X),
 	/* GFX domain clocks */
 	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_243X),
@@ -1901,6 +1905,7 @@ static struct omap_clk omap2430_clks[] = {
 	/* L4 domain clocks */
 	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X),
 	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X),
+	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_243X),
 	/* virtual meta-group clock */
 	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X),
 	/* general l4 interface ck, multi-parent functional clk */
@@ -2028,6 +2033,9 @@ int __init omap2430_clk_init(void)
 		omap2_init_clk_clkdm(c->lk.clk);
 	}
 
+	/* Disable autoidle on all clocks; let the PM code enable it later */
+	omap_clk_disable_autoidle_all();
+
 	/* Check the MPU rate set by bootloader */
 	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
 	for (prcm = rate_table; prcm->mpu_speed; prcm++) {

+ 2 - 2
arch/arm/mach-omap2/clock2xxx.h

@@ -23,13 +23,13 @@ void omap2xxx_clk_prepare_for_reboot(void);
 #ifdef CONFIG_SOC_OMAP2420
 int omap2420_clk_init(void);
 #else
-#define omap2420_clk_init()	0
+#define omap2420_clk_init()	do { } while(0)
 #endif
 
 #ifdef CONFIG_SOC_OMAP2430
 int omap2430_clk_init(void);
 #else
-#define omap2430_clk_init()	0
+#define omap2430_clk_init()	do { } while(0)
 #endif
 
 extern void __iomem *prcm_clksrc_ctrl, *cm_idlest_pll;

+ 28 - 1
arch/arm/mach-omap2/clock34xx.c

@@ -2,7 +2,7 @@
  * OMAP3-specific clock framework functions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Paul Walmsley
  * Jouni Högander
@@ -59,6 +59,15 @@ const struct clkops clkops_omap3430es2_ssi_wait = {
 	.find_companion = omap2_clk_dflt_find_companion,
 };
 
+const struct clkops clkops_omap3430es2_iclk_ssi_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap3430es2_clk_ssi_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};
+
 /**
  * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST
  * @clk: struct clk * being enabled
@@ -94,6 +103,15 @@ const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
 	.find_companion = omap2_clk_dflt_find_companion,
 };
 
+const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap3430es2_clk_dss_usbhost_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};
+
 /**
  * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB
  * @clk: struct clk * being enabled
@@ -124,3 +142,12 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = {
 	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
 	.find_companion = omap2_clk_dflt_find_companion,
 };
+
+const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};

+ 4 - 1
arch/arm/mach-omap2/clock34xx.h

@@ -2,14 +2,17 @@
  * OMAP34xx clock function prototypes and macros
  *
  * Copyright (C) 2007-2010 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  */
 
 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
 #define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
 
 extern const struct clkops clkops_omap3430es2_ssi_wait;
+extern const struct clkops clkops_omap3430es2_iclk_ssi_wait;
 extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
+extern const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait;
 extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
+extern const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait;
 
 #endif

+ 3 - 1
arch/arm/mach-omap2/clock3517.c

@@ -2,7 +2,7 @@
  * OMAP3517/3505-specific clock framework functions
  *
  * Copyright (C) 2010 Texas Instruments, Inc.
- * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2011 Nokia Corporation
  *
  * Ranjith Lohithakshan
  * Paul Walmsley
@@ -119,6 +119,8 @@ const struct clkops clkops_am35xx_ipss_wait = {
 	.disable	= omap2_dflt_clk_disable,
 	.find_idlest	= am35xx_clk_ipss_find_idlest,
 	.find_companion	= omap2_clk_dflt_find_companion,
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
 };
 
 

+ 0 - 3
arch/arm/mach-omap2/clock3xxx.c

@@ -65,9 +65,6 @@ void __init omap3_clk_lock_dpll5(void)
 	clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
 	clk_enable(dpll5_clk);
 
-	/* Enable autoidle to allow it to enter low power bypass */
-	omap3_dpll_allow_idle(dpll5_clk);
-
 	/* Program dpll5_m2_clk divider for no division */
 	dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
 	clk_enable(dpll5_m2_clk);

+ 84 - 81
arch/arm/mach-omap2/clock3xxx_data.c

@@ -2,7 +2,7 @@
  * OMAP3 clock data
  *
  * Copyright (C) 2007-2010 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Written by Paul Walmsley
  * With many device clock fixes by Kevin Hilman and Jouni Högander
@@ -291,12 +291,11 @@ static struct dpll_data dpll1_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll1_ck = {
 	.name		= "dpll1_ck",
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap3_noncore_dpll_ops,
 	.parent		= &sys_ck,
 	.dpll_data	= &dpll1_dd,
 	.round_rate	= &omap2_dpll_round_rate,
@@ -364,7 +363,6 @@ static struct dpll_data dpll2_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll2_ck = {
@@ -424,12 +422,11 @@ static struct dpll_data dpll3_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll3_ck = {
 	.name		= "dpll3_ck",
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap3_core_dpll_ops,
 	.parent		= &sys_ck,
 	.dpll_data	= &dpll3_dd,
 	.round_rate	= &omap2_dpll_round_rate,
@@ -583,7 +580,6 @@ static struct dpll_data dpll4_dd_34xx __initdata = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct dpll_data dpll4_dd_3630 __initdata = {
@@ -607,7 +603,6 @@ static struct dpll_data dpll4_dd_3630 __initdata = {
 	.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE,
 	.flags		= DPLL_J_TYPE
 };
 
@@ -939,7 +934,6 @@ static struct dpll_data dpll5_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll5_ck = {
@@ -1205,7 +1199,10 @@ static const struct clksel gfx_l3_clksel[] = {
 	{ .parent = NULL }
 };
 
-/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
+/*
+ * Virtual parent clock for gfx_l3_ick and gfx_l3_fck
+ * This interface clock does not have a CM_AUTOIDLE bit
+ */
 static struct clk gfx_l3_ck = {
 	.name		= "gfx_l3_ck",
 	.ops		= &clkops_omap2_dflt_wait,
@@ -1304,6 +1301,7 @@ static struct clk sgx_fck = {
 	.round_rate	= &omap2_clksel_round_rate
 };
 
+/* This interface clock does not have a CM_AUTOIDLE bit */
 static struct clk sgx_ick = {
 	.name		= "sgx_ick",
 	.ops		= &clkops_omap2_dflt_wait,
@@ -1328,7 +1326,7 @@ static struct clk d2d_26m_fck = {
 
 static struct clk modem_fck = {
 	.name		= "modem_fck",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_mdmclk_dflt_wait,
 	.parent		= &sys_ck,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
@@ -1338,7 +1336,7 @@ static struct clk modem_fck = {
 
 static struct clk sad2d_ick = {
 	.name		= "sad2d_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l3_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
@@ -1348,7 +1346,7 @@ static struct clk sad2d_ick = {
 
 static struct clk mad2d_ick = {
 	.name		= "mad2d_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l3_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
 	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
@@ -1718,7 +1716,7 @@ static struct clk core_l3_ick = {
 
 static struct clk hsotgusb_ick_3430es1 = {
 	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &core_l3_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
@@ -1728,7 +1726,7 @@ static struct clk hsotgusb_ick_3430es1 = {
 
 static struct clk hsotgusb_ick_3430es2 = {
 	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap3430es2_hsotgusb_wait,
+	.ops		= &clkops_omap3430es2_iclk_hsotgusb_wait,
 	.parent		= &core_l3_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
@@ -1736,6 +1734,7 @@ static struct clk hsotgusb_ick_3430es2 = {
 	.recalc		= &followparent_recalc,
 };
 
+/* This interface clock does not have a CM_AUTOIDLE bit */
 static struct clk sdrc_ick = {
 	.name		= "sdrc_ick",
 	.ops		= &clkops_omap2_dflt_wait,
@@ -1767,7 +1766,7 @@ static struct clk security_l3_ick = {
 
 static struct clk pka_ick = {
 	.name		= "pka_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &security_l3_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
@@ -1786,7 +1785,7 @@ static struct clk core_l4_ick = {
 
 static struct clk usbtll_ick = {
 	.name		= "usbtll_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
 	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
@@ -1796,7 +1795,7 @@ static struct clk usbtll_ick = {
 
 static struct clk mmchs3_ick = {
 	.name		= "mmchs3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
@@ -1807,7 +1806,7 @@ static struct clk mmchs3_ick = {
 /* Intersystem Communication Registers - chassis mode only */
 static struct clk icr_ick = {
 	.name		= "icr_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
@@ -1817,7 +1816,7 @@ static struct clk icr_ick = {
 
 static struct clk aes2_ick = {
 	.name		= "aes2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
@@ -1827,7 +1826,7 @@ static struct clk aes2_ick = {
 
 static struct clk sha12_ick = {
 	.name		= "sha12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
@@ -1837,7 +1836,7 @@ static struct clk sha12_ick = {
 
 static struct clk des2_ick = {
 	.name		= "des2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
@@ -1847,7 +1846,7 @@ static struct clk des2_ick = {
 
 static struct clk mmchs2_ick = {
 	.name		= "mmchs2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
@@ -1857,7 +1856,7 @@ static struct clk mmchs2_ick = {
 
 static struct clk mmchs1_ick = {
 	.name		= "mmchs1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
@@ -1867,7 +1866,7 @@ static struct clk mmchs1_ick = {
 
 static struct clk mspro_ick = {
 	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
@@ -1877,7 +1876,7 @@ static struct clk mspro_ick = {
 
 static struct clk hdq_ick = {
 	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
@@ -1887,7 +1886,7 @@ static struct clk hdq_ick = {
 
 static struct clk mcspi4_ick = {
 	.name		= "mcspi4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
@@ -1897,7 +1896,7 @@ static struct clk mcspi4_ick = {
 
 static struct clk mcspi3_ick = {
 	.name		= "mcspi3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
@@ -1907,7 +1906,7 @@ static struct clk mcspi3_ick = {
 
 static struct clk mcspi2_ick = {
 	.name		= "mcspi2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
@@ -1917,7 +1916,7 @@ static struct clk mcspi2_ick = {
 
 static struct clk mcspi1_ick = {
 	.name		= "mcspi1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
@@ -1927,7 +1926,7 @@ static struct clk mcspi1_ick = {
 
 static struct clk i2c3_ick = {
 	.name		= "i2c3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
@@ -1937,7 +1936,7 @@ static struct clk i2c3_ick = {
 
 static struct clk i2c2_ick = {
 	.name		= "i2c2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
@@ -1947,7 +1946,7 @@ static struct clk i2c2_ick = {
 
 static struct clk i2c1_ick = {
 	.name		= "i2c1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
@@ -1957,7 +1956,7 @@ static struct clk i2c1_ick = {
 
 static struct clk uart2_ick = {
 	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
@@ -1967,7 +1966,7 @@ static struct clk uart2_ick = {
 
 static struct clk uart1_ick = {
 	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
@@ -1977,7 +1976,7 @@ static struct clk uart1_ick = {
 
 static struct clk gpt11_ick = {
 	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
@@ -1987,7 +1986,7 @@ static struct clk gpt11_ick = {
 
 static struct clk gpt10_ick = {
 	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
@@ -1997,7 +1996,7 @@ static struct clk gpt10_ick = {
 
 static struct clk mcbsp5_ick = {
 	.name		= "mcbsp5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
@@ -2007,7 +2006,7 @@ static struct clk mcbsp5_ick = {
 
 static struct clk mcbsp1_ick = {
 	.name		= "mcbsp1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
@@ -2017,7 +2016,7 @@ static struct clk mcbsp1_ick = {
 
 static struct clk fac_ick = {
 	.name		= "fac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
@@ -2027,7 +2026,7 @@ static struct clk fac_ick = {
 
 static struct clk mailboxes_ick = {
 	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
@@ -2037,7 +2036,7 @@ static struct clk mailboxes_ick = {
 
 static struct clk omapctrl_ick = {
 	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
@@ -2057,7 +2056,7 @@ static struct clk ssi_l4_ick = {
 
 static struct clk ssi_ick_3430es1 = {
 	.name		= "ssi_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &ssi_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
@@ -2067,7 +2066,7 @@ static struct clk ssi_ick_3430es1 = {
 
 static struct clk ssi_ick_3430es2 = {
 	.name		= "ssi_ick",
-	.ops		= &clkops_omap3430es2_ssi_wait,
+	.ops		= &clkops_omap3430es2_iclk_ssi_wait,
 	.parent		= &ssi_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
@@ -2085,7 +2084,7 @@ static const struct clksel usb_l4_clksel[] = {
 
 static struct clk usb_l4_ick = {
 	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &l4_ick,
 	.init		= &omap2_init_clksel_parent,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -2107,7 +2106,7 @@ static struct clk security_l4_ick2 = {
 
 static struct clk aes1_ick = {
 	.name		= "aes1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &security_l4_ick2,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
@@ -2116,7 +2115,7 @@ static struct clk aes1_ick = {
 
 static struct clk rng_ick = {
 	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &security_l4_ick2,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
@@ -2125,7 +2124,7 @@ static struct clk rng_ick = {
 
 static struct clk sha11_ick = {
 	.name		= "sha11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &security_l4_ick2,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
@@ -2134,7 +2133,7 @@ static struct clk sha11_ick = {
 
 static struct clk des1_ick = {
 	.name		= "des1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &security_l4_ick2,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
@@ -2195,7 +2194,7 @@ static struct clk dss2_alwon_fck = {
 static struct clk dss_ick_3430es1 = {
 	/* Handles both L3 and L4 clocks */
 	.name		= "dss_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
@@ -2206,7 +2205,7 @@ static struct clk dss_ick_3430es1 = {
 static struct clk dss_ick_3430es2 = {
 	/* Handles both L3 and L4 clocks */
 	.name		= "dss_ick",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.ops		= &clkops_omap3430es2_iclk_dss_usbhost_wait,
 	.parent		= &l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
@@ -2229,7 +2228,7 @@ static struct clk cam_mclk = {
 static struct clk cam_ick = {
 	/* Handles both L3 and L4 clocks */
 	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt,
+	.ops		= &clkops_omap2_iclk_dflt,
 	.parent		= &l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
@@ -2272,7 +2271,7 @@ static struct clk usbhost_48m_fck = {
 static struct clk usbhost_ick = {
 	/* Handles both L3 and L4 clocks */
 	.name		= "usbhost_ick",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.ops		= &clkops_omap3430es2_iclk_dss_usbhost_wait,
 	.parent		= &l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
@@ -2372,7 +2371,7 @@ static struct clk wkup_l4_ick = {
 /* Never specifically named in the TRM, so we have to infer a likely name */
 static struct clk usim_ick = {
 	.name		= "usim_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &wkup_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
@@ -2382,7 +2381,7 @@ static struct clk usim_ick = {
 
 static struct clk wdt2_ick = {
 	.name		= "wdt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &wkup_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
@@ -2392,7 +2391,7 @@ static struct clk wdt2_ick = {
 
 static struct clk wdt1_ick = {
 	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &wkup_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
@@ -2402,7 +2401,7 @@ static struct clk wdt1_ick = {
 
 static struct clk gpio1_ick = {
 	.name		= "gpio1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &wkup_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
@@ -2412,7 +2411,7 @@ static struct clk gpio1_ick = {
 
 static struct clk omap_32ksync_ick = {
 	.name		= "omap_32ksync_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &wkup_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
@@ -2423,7 +2422,7 @@ static struct clk omap_32ksync_ick = {
 /* XXX This clock no longer exists in 3430 TRM rev F */
 static struct clk gpt12_ick = {
 	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &wkup_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
@@ -2433,7 +2432,7 @@ static struct clk gpt12_ick = {
 
 static struct clk gpt1_ick = {
 	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &wkup_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
@@ -2663,7 +2662,7 @@ static struct clk per_l4_ick = {
 
 static struct clk gpio6_ick = {
 	.name		= "gpio6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
@@ -2673,7 +2672,7 @@ static struct clk gpio6_ick = {
 
 static struct clk gpio5_ick = {
 	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
@@ -2683,7 +2682,7 @@ static struct clk gpio5_ick = {
 
 static struct clk gpio4_ick = {
 	.name		= "gpio4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
@@ -2693,7 +2692,7 @@ static struct clk gpio4_ick = {
 
 static struct clk gpio3_ick = {
 	.name		= "gpio3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
@@ -2703,7 +2702,7 @@ static struct clk gpio3_ick = {
 
 static struct clk gpio2_ick = {
 	.name		= "gpio2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
@@ -2713,7 +2712,7 @@ static struct clk gpio2_ick = {
 
 static struct clk wdt3_ick = {
 	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
@@ -2723,7 +2722,7 @@ static struct clk wdt3_ick = {
 
 static struct clk uart3_ick = {
 	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
@@ -2733,7 +2732,7 @@ static struct clk uart3_ick = {
 
 static struct clk uart4_ick = {
 	.name		= "uart4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3630_EN_UART4_SHIFT,
@@ -2743,7 +2742,7 @@ static struct clk uart4_ick = {
 
 static struct clk gpt9_ick = {
 	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
@@ -2753,7 +2752,7 @@ static struct clk gpt9_ick = {
 
 static struct clk gpt8_ick = {
 	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
@@ -2763,7 +2762,7 @@ static struct clk gpt8_ick = {
 
 static struct clk gpt7_ick = {
 	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
@@ -2773,7 +2772,7 @@ static struct clk gpt7_ick = {
 
 static struct clk gpt6_ick = {
 	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
@@ -2783,7 +2782,7 @@ static struct clk gpt6_ick = {
 
 static struct clk gpt5_ick = {
 	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
@@ -2793,7 +2792,7 @@ static struct clk gpt5_ick = {
 
 static struct clk gpt4_ick = {
 	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
@@ -2803,7 +2802,7 @@ static struct clk gpt4_ick = {
 
 static struct clk gpt3_ick = {
 	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
@@ -2813,7 +2812,7 @@ static struct clk gpt3_ick = {
 
 static struct clk gpt2_ick = {
 	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
@@ -2823,7 +2822,7 @@ static struct clk gpt2_ick = {
 
 static struct clk mcbsp2_ick = {
 	.name		= "mcbsp2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
@@ -2833,7 +2832,7 @@ static struct clk mcbsp2_ick = {
 
 static struct clk mcbsp3_ick = {
 	.name		= "mcbsp3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
@@ -2843,7 +2842,7 @@ static struct clk mcbsp3_ick = {
 
 static struct clk mcbsp4_ick = {
 	.name		= "mcbsp4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &per_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
@@ -3186,7 +3185,7 @@ static struct clk vpfe_fck = {
  */
 static struct clk uart4_ick_am35xx = {
 	.name		= "uart4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
+	.ops		= &clkops_omap2_iclk_dflt_wait,
 	.parent		= &core_l4_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= AM35XX_EN_UART4_SHIFT,
@@ -3538,6 +3537,9 @@ int __init omap3xxx_clk_init(void)
 			omap2_init_clk_clkdm(c->lk.clk);
 		}
 
+	/* Disable autoidle on all clocks; let the PM code enable it later */
+	omap_clk_disable_autoidle_all();
+
 	recalculate_root_clocks();
 
 	pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
@@ -3551,7 +3553,8 @@ int __init omap3xxx_clk_init(void)
 	clk_enable_init_clocks();
 
 	/*
-	 * Lock DPLL5 and put it in autoidle.
+	 * Lock DPLL5 -- here only until other device init code can
+	 * handle this
 	 */
 	if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0))
 		omap3_clk_lock_dpll5();

+ 34 - 23
arch/arm/mach-omap2/clock44xx_data.c

@@ -278,8 +278,10 @@ static struct clk dpll_abe_ck = {
 static struct clk dpll_abe_x2_ck = {
 	.name		= "dpll_abe_x2_ck",
 	.parent		= &dpll_abe_ck,
-	.ops		= &clkops_null,
+	.flags		= CLOCK_CLKOUTX2,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap3_clkoutx2_recalc,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
 };
 
 static const struct clksel_rate div31_1to31_rates[] = {
@@ -328,7 +330,7 @@ static struct clk dpll_abe_m2x2_ck = {
 	.clksel		= dpll_abe_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -395,7 +397,7 @@ static struct clk dpll_abe_m3x2_ck = {
 	.clksel		= dpll_abe_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M3_DPLL_ABE,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -443,13 +445,14 @@ static struct clk dpll_core_ck = {
 	.parent		= &sys_clkin_ck,
 	.dpll_data	= &dpll_core_dd,
 	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap3_core_dpll_ops,
 	.recalc		= &omap3_dpll_recalc,
 };
 
 static struct clk dpll_core_x2_ck = {
 	.name		= "dpll_core_x2_ck",
 	.parent		= &dpll_core_ck,
+	.flags		= CLOCK_CLKOUTX2,
 	.ops		= &clkops_null,
 	.recalc		= &omap3_clkoutx2_recalc,
 };
@@ -465,7 +468,7 @@ static struct clk dpll_core_m6x2_ck = {
 	.clksel		= dpll_core_m6x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M6_DPLL_CORE,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -495,7 +498,7 @@ static struct clk dpll_core_m2_ck = {
 	.clksel		= dpll_core_m2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_CORE,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -515,7 +518,7 @@ static struct clk dpll_core_m5x2_ck = {
 	.clksel		= dpll_core_m6x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_CORE,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -581,7 +584,7 @@ static struct clk dpll_core_m4x2_ck = {
 	.clksel		= dpll_core_m6x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_CORE,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -606,7 +609,7 @@ static struct clk dpll_abe_m2_ck = {
 	.clksel		= dpll_abe_m2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -632,7 +635,7 @@ static struct clk dpll_core_m7x2_ck = {
 	.clksel		= dpll_core_m6x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M7_DPLL_CORE,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -689,6 +692,7 @@ static struct clk dpll_iva_ck = {
 static struct clk dpll_iva_x2_ck = {
 	.name		= "dpll_iva_x2_ck",
 	.parent		= &dpll_iva_ck,
+	.flags		= CLOCK_CLKOUTX2,
 	.ops		= &clkops_null,
 	.recalc		= &omap3_clkoutx2_recalc,
 };
@@ -704,7 +708,7 @@ static struct clk dpll_iva_m4x2_ck = {
 	.clksel		= dpll_iva_m4x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_IVA,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -716,7 +720,7 @@ static struct clk dpll_iva_m5x2_ck = {
 	.clksel		= dpll_iva_m4x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_IVA,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -764,7 +768,7 @@ static struct clk dpll_mpu_m2_ck = {
 	.clksel		= dpll_mpu_m2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_MPU,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -837,7 +841,7 @@ static struct clk dpll_per_m2_ck = {
 	.clksel		= dpll_per_m2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -846,8 +850,10 @@ static struct clk dpll_per_m2_ck = {
 static struct clk dpll_per_x2_ck = {
 	.name		= "dpll_per_x2_ck",
 	.parent		= &dpll_per_ck,
-	.ops		= &clkops_null,
+	.flags		= CLOCK_CLKOUTX2,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap3_clkoutx2_recalc,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
 };
 
 static const struct clksel dpll_per_m2x2_div[] = {
@@ -861,7 +867,7 @@ static struct clk dpll_per_m2x2_ck = {
 	.clksel		= dpll_per_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -887,7 +893,7 @@ static struct clk dpll_per_m4x2_ck = {
 	.clksel		= dpll_per_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_PER,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -899,7 +905,7 @@ static struct clk dpll_per_m5x2_ck = {
 	.clksel		= dpll_per_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_PER,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -911,7 +917,7 @@ static struct clk dpll_per_m6x2_ck = {
 	.clksel		= dpll_per_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M6_DPLL_PER,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -923,7 +929,7 @@ static struct clk dpll_per_m7x2_ck = {
 	.clksel		= dpll_per_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M7_DPLL_PER,
 	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -964,6 +970,7 @@ static struct clk dpll_unipro_ck = {
 static struct clk dpll_unipro_x2_ck = {
 	.name		= "dpll_unipro_x2_ck",
 	.parent		= &dpll_unipro_ck,
+	.flags		= CLOCK_CLKOUTX2,
 	.ops		= &clkops_null,
 	.recalc		= &omap3_clkoutx2_recalc,
 };
@@ -979,7 +986,7 @@ static struct clk dpll_unipro_m2x2_ck = {
 	.clksel		= dpll_unipro_m2x2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_UNIPRO,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -1028,7 +1035,8 @@ static struct clk dpll_usb_ck = {
 static struct clk dpll_usb_clkdcoldo_ck = {
 	.name		= "dpll_usb_clkdcoldo_ck",
 	.parent		= &dpll_usb_ck,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
+	.clksel_reg	= OMAP4430_CM_CLKDCOLDO_DPLL_USB,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1043,7 +1051,7 @@ static struct clk dpll_usb_m2_ck = {
 	.clksel		= dpll_usb_m2_div,
 	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_USB,
 	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK,
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap4_dpllmx_ops,
 	.recalc		= &omap2_clksel_recalc,
 	.round_rate	= &omap2_clksel_round_rate,
 	.set_rate	= &omap2_clksel_set_rate,
@@ -3301,6 +3309,9 @@ int __init omap4xxx_clk_init(void)
 			omap2_init_clk_clkdm(c->lk.clk);
 		}
 
+	/* Disable autoidle on all clocks; let the PM code enable it later */
+	omap_clk_disable_autoidle_all();
+
 	recalculate_root_clocks();
 
 	/*

+ 6 - 0
arch/arm/mach-omap2/clock_common_data.c

@@ -37,3 +37,9 @@ const struct clksel_rate gfx_l3_rates[] = {
 	{ .div = 0 }
 };
 
+const struct clksel_rate dsp_ick_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_243X },
+	{ .div = 0 },
+};

+ 143 - 296
arch/arm/mach-omap2/clockdomain.c

@@ -26,17 +26,8 @@
 
 #include <linux/bitops.h>
 
-#include "prm2xxx_3xxx.h"
-#include "prm-regbits-24xx.h"
-#include "cm2xxx_3xxx.h"
-#include "cm-regbits-24xx.h"
-#include "cminst44xx.h"
-#include "prcm44xx.h"
-
 #include <plat/clock.h>
-#include "powerdomain.h"
 #include "clockdomain.h"
-#include <plat/prcm.h>
 
 /* clkdm_list contains all registered struct clockdomains */
 static LIST_HEAD(clkdm_list);
@@ -44,6 +35,7 @@ static LIST_HEAD(clkdm_list);
 /* array of clockdomain deps to be added/removed when clkdm in hwsup mode */
 static struct clkdm_autodep *autodeps;
 
+static struct clkdm_ops *arch_clkdm;
 
 /* Private functions */
 
@@ -177,11 +169,11 @@ static void _autodep_lookup(struct clkdm_autodep *autodep)
  * XXX autodeps are deprecated and should be removed at the earliest
  * opportunity
  */
-static void _clkdm_add_autodeps(struct clockdomain *clkdm)
+void _clkdm_add_autodeps(struct clockdomain *clkdm)
 {
 	struct clkdm_autodep *autodep;
 
-	if (!autodeps)
+	if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
 		return;
 
 	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
@@ -211,11 +203,11 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)
  * XXX autodeps are deprecated and should be removed at the earliest
  * opportunity
  */
-static void _clkdm_del_autodeps(struct clockdomain *clkdm)
+void _clkdm_del_autodeps(struct clockdomain *clkdm)
 {
 	struct clkdm_autodep *autodep;
 
-	if (!autodeps)
+	if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
 		return;
 
 	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
@@ -235,55 +227,29 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
 }
 
 /**
- * _enable_hwsup - place a clockdomain into hardware-supervised idle
- * @clkdm: struct clockdomain *
- *
- * Place the clockdomain into hardware-supervised idle mode.  No return
- * value.
+ * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms
+ * @clkdm: clockdomain that we are resolving dependencies for
+ * @clkdm_deps: ptr to array of struct clkdm_deps to resolve
  *
- * XXX Should this return an error if the clockdomain does not support
- * hardware-supervised idle mode?
- */
-static void _enable_hwsup(struct clockdomain *clkdm)
-{
-	if (cpu_is_omap24xx())
-		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					       clkdm->clktrctrl_mask);
-	else if (cpu_is_omap34xx())
-		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-					       clkdm->clktrctrl_mask);
-	else if (cpu_is_omap44xx())
-		return omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
-						       clkdm->cm_inst,
-						       clkdm->clkdm_offs);
-	else
-		BUG();
-}
-
-/**
- * _disable_hwsup - place a clockdomain into software-supervised idle
- * @clkdm: struct clockdomain *
- *
- * Place the clockdomain @clkdm into software-supervised idle mode.
+ * Iterates through @clkdm_deps, looking up the struct clockdomain named by
+ * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep.
  * No return value.
- *
- * XXX Should this return an error if the clockdomain does not support
- * software-supervised idle mode?
  */
-static void _disable_hwsup(struct clockdomain *clkdm)
+static void _resolve_clkdm_deps(struct clockdomain *clkdm,
+				struct clkdm_dep *clkdm_deps)
 {
-	if (cpu_is_omap24xx())
-		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-						clkdm->clktrctrl_mask);
-	else if (cpu_is_omap34xx())
-		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-						clkdm->clktrctrl_mask);
-	else if (cpu_is_omap44xx())
-		return omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
-							clkdm->cm_inst,
-							clkdm->clkdm_offs);
-	else
-		BUG();
+	struct clkdm_dep *cd;
+
+	for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+		if (cd->clkdm)
+			continue;
+		cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
+		WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen",
+		     clkdm->name, cd->clkdm_name);
+	}
 }
 
 /* Public functions */
@@ -292,6 +258,7 @@ static void _disable_hwsup(struct clockdomain *clkdm)
  * clkdm_init - set up the clockdomain layer
  * @clkdms: optional pointer to an array of clockdomains to register
  * @init_autodeps: optional pointer to an array of autodeps to register
+ * @custom_funcs: func pointers for arch specfic implementations
  *
  * Set up internal state.  If a pointer to an array of clockdomains
  * @clkdms was supplied, loop through the list of clockdomains,
@@ -300,12 +267,18 @@ static void _disable_hwsup(struct clockdomain *clkdm)
  * @init_autodeps was provided, register those.  No return value.
  */
 void clkdm_init(struct clockdomain **clkdms,
-		struct clkdm_autodep *init_autodeps)
+		struct clkdm_autodep *init_autodeps,
+		struct clkdm_ops *custom_funcs)
 {
 	struct clockdomain **c = NULL;
 	struct clockdomain *clkdm;
 	struct clkdm_autodep *autodep = NULL;
 
+	if (!custom_funcs)
+		WARN(1, "No custom clkdm functions registered\n");
+	else
+		arch_clkdm = custom_funcs;
+
 	if (clkdms)
 		for (c = clkdms; *c; c++)
 			_clkdm_register(*c);
@@ -321,11 +294,14 @@ void clkdm_init(struct clockdomain **clkdms,
 	 */
 	list_for_each_entry(clkdm, &clkdm_list, node) {
 		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-			omap2_clkdm_wakeup(clkdm);
+			clkdm_wakeup(clkdm);
 		else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
-			omap2_clkdm_deny_idle(clkdm);
+			clkdm_deny_idle(clkdm);
 
+		_resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs);
 		clkdm_clear_all_wkdeps(clkdm);
+
+		_resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs);
 		clkdm_clear_all_sleepdeps(clkdm);
 	}
 }
@@ -422,32 +398,32 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
 int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
 	struct clkdm_dep *cd;
-
-	if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
-		pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
-		       clkdm1->name, clkdm2->name, __func__);
-		return -EINVAL;
-	}
+	int ret = 0;
 
 	if (!clkdm1 || !clkdm2)
 		return -EINVAL;
 
 	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
-	if (IS_ERR(cd)) {
+	if (IS_ERR(cd))
+		ret = PTR_ERR(cd);
+
+	if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
+		ret = -EINVAL;
+
+	if (ret) {
 		pr_debug("clockdomain: hardware cannot set/clear wake up of "
 			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
-		return PTR_ERR(cd);
+		return ret;
 	}
 
 	if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
 		pr_debug("clockdomain: hardware will wake up %s when %s wakes "
 			 "up\n", clkdm1->name, clkdm2->name);
 
-		omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
-				     clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+		ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
 	}
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -463,32 +439,32 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
 	struct clkdm_dep *cd;
-
-	if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
-		pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
-		       clkdm1->name, clkdm2->name, __func__);
-		return -EINVAL;
-	}
+	int ret = 0;
 
 	if (!clkdm1 || !clkdm2)
 		return -EINVAL;
 
 	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
-	if (IS_ERR(cd)) {
+	if (IS_ERR(cd))
+		ret = PTR_ERR(cd);
+
+	if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep)
+		ret = -EINVAL;
+
+	if (ret) {
 		pr_debug("clockdomain: hardware cannot set/clear wake up of "
 			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
-		return PTR_ERR(cd);
+		return ret;
 	}
 
 	if (atomic_dec_return(&cd->wkdep_usecount) == 0) {
 		pr_debug("clockdomain: hardware will no longer wake up %s "
 			 "after %s wakes up\n", clkdm1->name, clkdm2->name);
 
-		omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
-				       clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+		ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
 	}
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -508,26 +484,26 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
 	struct clkdm_dep *cd;
+	int ret = 0;
 
 	if (!clkdm1 || !clkdm2)
 		return -EINVAL;
 
-	if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
-		pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
-		       clkdm1->name, clkdm2->name, __func__);
-		return -EINVAL;
-	}
-
 	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
-	if (IS_ERR(cd)) {
+	if (IS_ERR(cd))
+		ret = PTR_ERR(cd);
+
+	if (!arch_clkdm || !arch_clkdm->clkdm_read_wkdep)
+		ret = -EINVAL;
+
+	if (ret) {
 		pr_debug("clockdomain: hardware cannot set/clear wake up of "
 			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
-		return PTR_ERR(cd);
+		return ret;
 	}
 
 	/* XXX It's faster to return the atomic wkdep_usecount */
-	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP,
-				       (1 << clkdm2->dep_bit));
+	return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
 }
 
 /**
@@ -542,33 +518,13 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
  */
 int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
 {
-	struct clkdm_dep *cd;
-	u32 mask = 0;
-
-	if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
-		pr_err("clockdomain: %s: %s: not yet implemented\n",
-		       clkdm->name, __func__);
-		return -EINVAL;
-	}
-
 	if (!clkdm)
 		return -EINVAL;
 
-	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
-		if (!omap_chip_is(cd->omap_chip))
-			continue;
-
-		if (!cd->clkdm && cd->clkdm_name)
-			cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
-		/* PRM accesses are slow, so minimize them */
-		mask |= 1 << cd->clkdm->dep_bit;
-		atomic_set(&cd->wkdep_usecount, 0);
-	}
-
-	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP);
+	if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_wkdeps)
+		return -EINVAL;
 
-	return 0;
+	return arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
 }
 
 /**
@@ -586,31 +542,33 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
 int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
 	struct clkdm_dep *cd;
-
-	if (!cpu_is_omap34xx())
-		return -EINVAL;
+	int ret = 0;
 
 	if (!clkdm1 || !clkdm2)
 		return -EINVAL;
 
 	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
-	if (IS_ERR(cd)) {
+	if (IS_ERR(cd))
+		ret = PTR_ERR(cd);
+
+	if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep)
+		ret = -EINVAL;
+
+	if (ret) {
 		pr_debug("clockdomain: hardware cannot set/clear sleep "
 			 "dependency affecting %s from %s\n", clkdm1->name,
 			 clkdm2->name);
-		return PTR_ERR(cd);
+		return ret;
 	}
 
 	if (atomic_inc_return(&cd->sleepdep_usecount) == 1) {
 		pr_debug("clockdomain: will prevent %s from sleeping if %s "
 			 "is active\n", clkdm1->name, clkdm2->name);
 
-		omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
-				    clkdm1->pwrdm.ptr->prcm_offs,
-				    OMAP3430_CM_SLEEPDEP);
+		ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
 	}
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -628,19 +586,23 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
 	struct clkdm_dep *cd;
-
-	if (!cpu_is_omap34xx())
-		return -EINVAL;
+	int ret = 0;
 
 	if (!clkdm1 || !clkdm2)
 		return -EINVAL;
 
 	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
-	if (IS_ERR(cd)) {
+	if (IS_ERR(cd))
+		ret = PTR_ERR(cd);
+
+	if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep)
+		ret = -EINVAL;
+
+	if (ret) {
 		pr_debug("clockdomain: hardware cannot set/clear sleep "
 			 "dependency affecting %s from %s\n", clkdm1->name,
 			 clkdm2->name);
-		return PTR_ERR(cd);
+		return ret;
 	}
 
 	if (atomic_dec_return(&cd->sleepdep_usecount) == 0) {
@@ -648,12 +610,10 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 			 "sleeping if %s is active\n", clkdm1->name,
 			 clkdm2->name);
 
-		omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
-				      clkdm1->pwrdm.ptr->prcm_offs,
-				      OMAP3430_CM_SLEEPDEP);
+		ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
 	}
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -675,25 +635,27 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
 	struct clkdm_dep *cd;
-
-	if (!cpu_is_omap34xx())
-		return -EINVAL;
+	int ret = 0;
 
 	if (!clkdm1 || !clkdm2)
 		return -EINVAL;
 
 	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
-	if (IS_ERR(cd)) {
+	if (IS_ERR(cd))
+		ret = PTR_ERR(cd);
+
+	if (!arch_clkdm || !arch_clkdm->clkdm_read_sleepdep)
+		ret = -EINVAL;
+
+	if (ret) {
 		pr_debug("clockdomain: hardware cannot set/clear sleep "
 			 "dependency affecting %s from %s\n", clkdm1->name,
 			 clkdm2->name);
-		return PTR_ERR(cd);
+		return ret;
 	}
 
 	/* XXX It's faster to return the atomic sleepdep_usecount */
-	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
-				       OMAP3430_CM_SLEEPDEP,
-				       (1 << clkdm2->dep_bit));
+	return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
 }
 
 /**
@@ -708,35 +670,17 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
  */
 int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
 {
-	struct clkdm_dep *cd;
-	u32 mask = 0;
-
-	if (!cpu_is_omap34xx())
-		return -EINVAL;
-
 	if (!clkdm)
 		return -EINVAL;
 
-	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
-		if (!omap_chip_is(cd->omap_chip))
-			continue;
-
-		if (!cd->clkdm && cd->clkdm_name)
-			cd->clkdm = _clkdm_lookup(cd->clkdm_name);
-
-		/* PRM accesses are slow, so minimize them */
-		mask |= 1 << cd->clkdm->dep_bit;
-		atomic_set(&cd->sleepdep_usecount, 0);
-	}
-
-	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
-			       OMAP3430_CM_SLEEPDEP);
+	if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_sleepdeps)
+		return -EINVAL;
 
-	return 0;
+	return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
 }
 
 /**
- * omap2_clkdm_sleep - force clockdomain sleep transition
+ * clkdm_sleep - force clockdomain sleep transition
  * @clkdm: struct clockdomain *
  *
  * Instruct the CM to force a sleep transition on the specified
@@ -744,7 +688,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
  * clockdomain does not support software-initiated sleep; 0 upon
  * success.
  */
-int omap2_clkdm_sleep(struct clockdomain *clkdm)
+int clkdm_sleep(struct clockdomain *clkdm)
 {
 	if (!clkdm)
 		return -EINVAL;
@@ -755,33 +699,16 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
 		return -EINVAL;
 	}
 
-	pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
-
-	if (cpu_is_omap24xx()) {
-
-		omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
-			    clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
-
-	} else if (cpu_is_omap34xx()) {
-
-		omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
-					      clkdm->clktrctrl_mask);
-
-	} else if (cpu_is_omap44xx()) {
-
-		omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
-					       clkdm->cm_inst,
-					       clkdm->clkdm_offs);
+	if (!arch_clkdm || !arch_clkdm->clkdm_sleep)
+		return -EINVAL;
 
-	} else {
-		BUG();
-	};
+	pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
 
-	return 0;
+	return arch_clkdm->clkdm_sleep(clkdm);
 }
 
 /**
- * omap2_clkdm_wakeup - force clockdomain wakeup transition
+ * clkdm_wakeup - force clockdomain wakeup transition
  * @clkdm: struct clockdomain *
  *
  * Instruct the CM to force a wakeup transition on the specified
@@ -789,7 +716,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
  * clockdomain does not support software-controlled wakeup; 0 upon
  * success.
  */
-int omap2_clkdm_wakeup(struct clockdomain *clkdm)
+int clkdm_wakeup(struct clockdomain *clkdm)
 {
 	if (!clkdm)
 		return -EINVAL;
@@ -800,33 +727,16 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
 		return -EINVAL;
 	}
 
-	pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
-
-	if (cpu_is_omap24xx()) {
-
-		omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
-			      clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
-
-	} else if (cpu_is_omap34xx()) {
-
-		omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
-					       clkdm->clktrctrl_mask);
-
-	} else if (cpu_is_omap44xx()) {
-
-		omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
-						clkdm->cm_inst,
-						clkdm->clkdm_offs);
+	if (!arch_clkdm || !arch_clkdm->clkdm_wakeup)
+		return -EINVAL;
 
-	} else {
-		BUG();
-	};
+	pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
 
-	return 0;
+	return arch_clkdm->clkdm_wakeup(clkdm);
 }
 
 /**
- * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
+ * clkdm_allow_idle - enable hwsup idle transitions for clkdm
  * @clkdm: struct clockdomain *
  *
  * Allow the hardware to automatically switch the clockdomain @clkdm into
@@ -835,7 +745,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
  * framework, wkdep/sleepdep autodependencies are added; this is so
  * device drivers can read and write to the device.  No return value.
  */
-void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+void clkdm_allow_idle(struct clockdomain *clkdm)
 {
 	if (!clkdm)
 		return;
@@ -846,27 +756,18 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
 		return;
 	}
 
+	if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle)
+		return;
+
 	pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
 		 clkdm->name);
 
-	/*
-	 * XXX This should be removed once TI adds wakeup/sleep
-	 * dependency code and data for OMAP4.
-	 */
-	if (cpu_is_omap44xx()) {
-		pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name);
-	} else {
-		if (atomic_read(&clkdm->usecount) > 0)
-			_clkdm_add_autodeps(clkdm);
-	}
-
-	_enable_hwsup(clkdm);
-
+	arch_clkdm->clkdm_allow_idle(clkdm);
 	pwrdm_clkdm_state_switch(clkdm);
 }
 
 /**
- * omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm
+ * clkdm_deny_idle - disable hwsup idle transitions for clkdm
  * @clkdm: struct clockdomain *
  *
  * Prevent the hardware from automatically switching the clockdomain
@@ -874,7 +775,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
  * downstream clocks enabled in the clock framework, wkdep/sleepdep
  * autodependencies are removed.  No return value.
  */
-void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+void clkdm_deny_idle(struct clockdomain *clkdm)
 {
 	if (!clkdm)
 		return;
@@ -885,28 +786,20 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
 		return;
 	}
 
+	if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle)
+		return;
+
 	pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
 		 clkdm->name);
 
-	_disable_hwsup(clkdm);
-
-	/*
-	 * XXX This should be removed once TI adds wakeup/sleep
-	 * dependency code and data for OMAP4.
-	 */
-	if (cpu_is_omap44xx()) {
-		pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name);
-	} else {
-		if (atomic_read(&clkdm->usecount) > 0)
-			_clkdm_del_autodeps(clkdm);
-	}
+	arch_clkdm->clkdm_deny_idle(clkdm);
 }
 
 
 /* Clockdomain-to-clock framework interface code */
 
 /**
- * omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm
+ * clkdm_clk_enable - add an enabled downstream clock to this clkdm
  * @clkdm: struct clockdomain *
  * @clk: struct clk * of the enabled downstream clock
  *
@@ -919,10 +812,8 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
  * by on-chip processors.  Returns -EINVAL if passed null pointers;
  * returns 0 upon success or if the clockdomain is in hwsup idle mode.
  */
-int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
+int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
 {
-	bool hwsup = false;
-
 	/*
 	 * XXX Rewrite this code to maintain a list of enabled
 	 * downstream clocks for debugging purposes?
@@ -931,6 +822,9 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
 	if (!clkdm || !clk)
 		return -EINVAL;
 
+	if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable)
+		return -EINVAL;
+
 	if (atomic_inc_return(&clkdm->usecount) > 1)
 		return 0;
 
@@ -939,31 +833,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
 	pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
 		 clk->name);
 
-	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-
-		if (!clkdm->clktrctrl_mask)
-			return 0;
-
-		hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-						   clkdm->clktrctrl_mask);
-
-	} else if (cpu_is_omap44xx()) {
-
-		hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
-						       clkdm->cm_inst,
-						       clkdm->clkdm_offs);
-
-	}
-
-	if (hwsup) {
-		/* Disable HW transitions when we are changing deps */
-		_disable_hwsup(clkdm);
-		_clkdm_add_autodeps(clkdm);
-		_enable_hwsup(clkdm);
-	} else {
-		omap2_clkdm_wakeup(clkdm);
-	}
-
+	arch_clkdm->clkdm_clk_enable(clkdm);
 	pwrdm_wait_transition(clkdm->pwrdm.ptr);
 	pwrdm_clkdm_state_switch(clkdm);
 
@@ -971,7 +841,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
 }
 
 /**
- * omap2_clkdm_clk_disable - remove an enabled downstream clock from this clkdm
+ * clkdm_clk_disable - remove an enabled downstream clock from this clkdm
  * @clkdm: struct clockdomain *
  * @clk: struct clk * of the disabled downstream clock
  *
@@ -984,10 +854,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
  * is enabled; or returns 0 upon success or if the clockdomain is in
  * hwsup idle mode.
  */
-int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
+int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
 {
-	bool hwsup = false;
-
 	/*
 	 * XXX Rewrite this code to maintain a list of enabled
 	 * downstream clocks for debugging purposes?
@@ -996,6 +864,9 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
 	if (!clkdm || !clk)
 		return -EINVAL;
 
+	if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable)
+		return -EINVAL;
+
 #ifdef DEBUG
 	if (atomic_read(&clkdm->usecount) == 0) {
 		WARN_ON(1); /* underflow */
@@ -1011,31 +882,7 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
 	pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
 		 clk->name);
 
-	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-
-		if (!clkdm->clktrctrl_mask)
-			return 0;
-
-		hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-						   clkdm->clktrctrl_mask);
-
-	} else if (cpu_is_omap44xx()) {
-
-		hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
-						       clkdm->cm_inst,
-						       clkdm->clkdm_offs);
-
-	}
-
-	if (hwsup) {
-		/* Disable HW transitions when we are changing deps */
-		_disable_hwsup(clkdm);
-		_clkdm_del_autodeps(clkdm);
-		_enable_hwsup(clkdm);
-	} else {
-		omap2_clkdm_sleep(clkdm);
-	}
-
+	arch_clkdm->clkdm_clk_disable(clkdm);
 	pwrdm_clkdm_state_switch(clkdm);
 
 	return 0;

+ 60 - 10
arch/arm/mach-omap2/clockdomain.h

@@ -4,7 +4,7 @@
  * OMAP2/3 clockdomain framework functions
  *
  * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008-2010 Nokia Corporation
+ * Copyright (C) 2008-2011 Nokia Corporation
  *
  * Paul Walmsley
  *
@@ -22,11 +22,19 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 
-/* Clockdomain capability flags */
+/*
+ * Clockdomain flags
+ *
+ * XXX Document CLKDM_CAN_* flags
+ *
+ * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this
+ *     clockdomain.  (Currently, this applies to OMAP3 clockdomains only.)
+ */
 #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
 #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
 #define CLKDM_CAN_ENABLE_AUTO			(1 << 2)
 #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
+#define CLKDM_NO_AUTODEPS			(1 << 4)
 
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -116,7 +124,42 @@ struct clockdomain {
 	struct list_head node;
 };
 
-void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps);
+/**
+ * struct clkdm_ops - Arch specfic function implementations
+ * @clkdm_add_wkdep: Add a wakeup dependency between clk domains
+ * @clkdm_del_wkdep: Delete a wakeup dependency between clk domains
+ * @clkdm_read_wkdep: Read wakeup dependency state between clk domains
+ * @clkdm_clear_all_wkdeps: Remove all wakeup dependencies from the clk domain
+ * @clkdm_add_sleepdep: Add a sleep dependency between clk domains
+ * @clkdm_del_sleepdep: Delete a sleep dependency between clk domains
+ * @clkdm_read_sleepdep: Read sleep dependency state between clk domains
+ * @clkdm_clear_all_sleepdeps: Remove all sleep dependencies from the clk domain
+ * @clkdm_sleep: Force a clockdomain to sleep
+ * @clkdm_wakeup: Force a clockdomain to wakeup
+ * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain
+ * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
+ * @clkdm_clk_enable: Put the clkdm in right state for a clock enable
+ * @clkdm_clk_disable: Put the clkdm in right state for a clock disable
+ */
+struct clkdm_ops {
+	int	(*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+	int	(*clkdm_del_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+	int	(*clkdm_read_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+	int	(*clkdm_clear_all_wkdeps)(struct clockdomain *clkdm);
+	int	(*clkdm_add_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+	int	(*clkdm_del_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+	int	(*clkdm_read_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+	int	(*clkdm_clear_all_sleepdeps)(struct clockdomain *clkdm);
+	int	(*clkdm_sleep)(struct clockdomain *clkdm);
+	int	(*clkdm_wakeup)(struct clockdomain *clkdm);
+	void	(*clkdm_allow_idle)(struct clockdomain *clkdm);
+	void	(*clkdm_deny_idle)(struct clockdomain *clkdm);
+	int	(*clkdm_clk_enable)(struct clockdomain *clkdm);
+	int	(*clkdm_clk_disable)(struct clockdomain *clkdm);
+};
+
+void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps,
+			struct clkdm_ops *custom_funcs);
 struct clockdomain *clkdm_lookup(const char *name);
 
 int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
@@ -132,16 +175,23 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
 int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
 int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
 
-void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
-void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
+void clkdm_allow_idle(struct clockdomain *clkdm);
+void clkdm_deny_idle(struct clockdomain *clkdm);
 
-int omap2_clkdm_wakeup(struct clockdomain *clkdm);
-int omap2_clkdm_sleep(struct clockdomain *clkdm);
+int clkdm_wakeup(struct clockdomain *clkdm);
+int clkdm_sleep(struct clockdomain *clkdm);
 
-int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
-int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
+int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
+int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
 
-extern void __init omap2_clockdomains_init(void);
+extern void __init omap2xxx_clockdomains_init(void);
+extern void __init omap3xxx_clockdomains_init(void);
 extern void __init omap44xx_clockdomains_init(void);
+extern void _clkdm_add_autodeps(struct clockdomain *clkdm);
+extern void _clkdm_del_autodeps(struct clockdomain *clkdm);
+
+extern struct clkdm_ops omap2_clkdm_operations;
+extern struct clkdm_ops omap3_clkdm_operations;
+extern struct clkdm_ops omap4_clkdm_operations;
 
 #endif

+ 274 - 0
arch/arm/mach-omap2/clockdomain2xxx_3xxx.c

@@ -0,0 +1,274 @@
+/*
+ * OMAP2 and OMAP3 clockdomain control
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <plat/prcm.h>
+#include "prm.h"
+#include "prm2xxx_3xxx.h"
+#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-24xx.h"
+#include "clockdomain.h"
+
+static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+						struct clockdomain *clkdm2)
+{
+	omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+	return 0;
+}
+
+static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+						 struct clockdomain *clkdm2)
+{
+	omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+	return 0;
+}
+
+static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+						 struct clockdomain *clkdm2)
+{
+	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+				PM_WKDEP, (1 << clkdm2->dep_bit));
+}
+
+static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+		if (!cd->clkdm)
+			continue; /* only happens if data is erroneous */
+
+		/* PRM accesses are slow, so minimize them */
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->wkdep_usecount, 0);
+	}
+
+	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+				 PM_WKDEP);
+	return 0;
+}
+
+static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
+						 struct clockdomain *clkdm2)
+{
+	omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+				clkdm1->pwrdm.ptr->prcm_offs,
+				OMAP3430_CM_SLEEPDEP);
+	return 0;
+}
+
+static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
+						 struct clockdomain *clkdm2)
+{
+	omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+				clkdm1->pwrdm.ptr->prcm_offs,
+				OMAP3430_CM_SLEEPDEP);
+	return 0;
+}
+
+static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
+						 struct clockdomain *clkdm2)
+{
+	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+				OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
+}
+
+static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+		if (!cd->clkdm)
+			continue; /* only happens if data is erroneous */
+
+		/* PRM accesses are slow, so minimize them */
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->sleepdep_usecount, 0);
+	}
+	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+				OMAP3430_CM_SLEEPDEP);
+	return 0;
+}
+
+static int omap2_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+				clkdm->pwrdm.ptr->prcm_offs,
+				OMAP2_PM_PWSTCTRL);
+	return 0;
+}
+
+static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+				clkdm->pwrdm.ptr->prcm_offs,
+				OMAP2_PM_PWSTCTRL);
+	return 0;
+}
+
+static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_add_autodeps(clkdm);
+
+	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+}
+
+static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_del_autodeps(clkdm);
+}
+
+static void _enable_hwsup(struct clockdomain *clkdm)
+{
+	if (cpu_is_omap24xx())
+		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					       clkdm->clktrctrl_mask);
+	else if (cpu_is_omap34xx())
+		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					       clkdm->clktrctrl_mask);
+}
+
+static void _disable_hwsup(struct clockdomain *clkdm)
+{
+	if (cpu_is_omap24xx())
+		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+						clkdm->clktrctrl_mask);
+	else if (cpu_is_omap34xx())
+		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+						clkdm->clktrctrl_mask);
+}
+
+
+static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	if (!clkdm->clktrctrl_mask)
+		return 0;
+
+	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+
+	if (hwsup) {
+		/* Disable HW transitions when we are changing deps */
+		_disable_hwsup(clkdm);
+		_clkdm_add_autodeps(clkdm);
+		_enable_hwsup(clkdm);
+	} else {
+		clkdm_wakeup(clkdm);
+	}
+
+	return 0;
+}
+
+static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	if (!clkdm->clktrctrl_mask)
+		return 0;
+
+	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+
+	if (hwsup) {
+		/* Disable HW transitions when we are changing deps */
+		_disable_hwsup(clkdm);
+		_clkdm_del_autodeps(clkdm);
+		_enable_hwsup(clkdm);
+	} else {
+		clkdm_sleep(clkdm);
+	}
+
+	return 0;
+}
+
+static int omap3_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_add_autodeps(clkdm);
+
+	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+}
+
+static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				clkdm->clktrctrl_mask);
+
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_del_autodeps(clkdm);
+}
+
+struct clkdm_ops omap2_clkdm_operations = {
+	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
+	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
+	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
+	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
+	.clkdm_sleep		= omap2_clkdm_sleep,
+	.clkdm_wakeup		= omap2_clkdm_wakeup,
+	.clkdm_allow_idle	= omap2_clkdm_allow_idle,
+	.clkdm_deny_idle	= omap2_clkdm_deny_idle,
+	.clkdm_clk_enable	= omap2_clkdm_clk_enable,
+	.clkdm_clk_disable	= omap2_clkdm_clk_disable,
+};
+
+struct clkdm_ops omap3_clkdm_operations = {
+	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
+	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
+	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep,
+	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps,
+	.clkdm_add_sleepdep	= omap3_clkdm_add_sleepdep,
+	.clkdm_del_sleepdep	= omap3_clkdm_del_sleepdep,
+	.clkdm_read_sleepdep	= omap3_clkdm_read_sleepdep,
+	.clkdm_clear_all_sleepdeps	= omap3_clkdm_clear_all_sleepdeps,
+	.clkdm_sleep		= omap3_clkdm_sleep,
+	.clkdm_wakeup		= omap3_clkdm_wakeup,
+	.clkdm_allow_idle	= omap3_clkdm_allow_idle,
+	.clkdm_deny_idle	= omap3_clkdm_deny_idle,
+	.clkdm_clk_enable	= omap2_clkdm_clk_enable,
+	.clkdm_clk_disable	= omap2_clkdm_clk_disable,
+};

+ 137 - 0
arch/arm/mach-omap2/clockdomain44xx.c

@@ -0,0 +1,137 @@
+/*
+ * OMAP4 clockdomain control
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include "clockdomain.h"
+#include "cminst44xx.h"
+#include "cm44xx.h"
+
+static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
+					struct clockdomain *clkdm2)
+{
+	omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
+					clkdm1->prcm_partition,
+					clkdm1->cm_inst, clkdm1->clkdm_offs +
+					OMAP4_CM_STATICDEP);
+	return 0;
+}
+
+static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
+					struct clockdomain *clkdm2)
+{
+	omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
+					clkdm1->prcm_partition,
+					clkdm1->cm_inst, clkdm1->clkdm_offs +
+					OMAP4_CM_STATICDEP);
+	return 0;
+}
+
+static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
+					struct clockdomain *clkdm2)
+{
+	return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
+					clkdm1->cm_inst, clkdm1->clkdm_offs +
+					OMAP4_CM_STATICDEP,
+					(1 << clkdm2->dep_bit));
+}
+
+static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
+{
+	struct clkdm_dep *cd;
+	u32 mask = 0;
+
+	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+		if (!omap_chip_is(cd->omap_chip))
+			continue;
+		if (!cd->clkdm)
+			continue; /* only happens if data is erroneous */
+
+		mask |= 1 << cd->clkdm->dep_bit;
+		atomic_set(&cd->wkdep_usecount, 0);
+	}
+
+	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs +
+					OMAP4_CM_STATICDEP);
+	return 0;
+}
+
+static int omap4_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+	return 0;
+}
+
+static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+	return 0;
+}
+
+static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+
+	if (!hwsup)
+		clkdm_wakeup(clkdm);
+
+	return 0;
+}
+
+static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+	bool hwsup = false;
+
+	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+					clkdm->cm_inst, clkdm->clkdm_offs);
+
+	if (!hwsup)
+		clkdm_sleep(clkdm);
+
+	return 0;
+}
+
+struct clkdm_ops omap4_clkdm_operations = {
+	.clkdm_add_wkdep	= omap4_clkdm_add_wkup_sleep_dep,
+	.clkdm_del_wkdep	= omap4_clkdm_del_wkup_sleep_dep,
+	.clkdm_read_wkdep	= omap4_clkdm_read_wkup_sleep_dep,
+	.clkdm_clear_all_wkdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
+	.clkdm_add_sleepdep	= omap4_clkdm_add_wkup_sleep_dep,
+	.clkdm_del_sleepdep	= omap4_clkdm_del_wkup_sleep_dep,
+	.clkdm_read_sleepdep	= omap4_clkdm_read_wkup_sleep_dep,
+	.clkdm_clear_all_sleepdeps	= omap4_clkdm_clear_all_wkup_sleep_deps,
+	.clkdm_sleep		= omap4_clkdm_sleep,
+	.clkdm_wakeup		= omap4_clkdm_wakeup,
+	.clkdm_allow_idle	= omap4_clkdm_allow_idle,
+	.clkdm_deny_idle	= omap4_clkdm_deny_idle,
+	.clkdm_clk_enable	= omap4_clkdm_clk_enable,
+	.clkdm_clk_disable	= omap4_clkdm_clk_disable,
+};

+ 10 - 2
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c

@@ -89,6 +89,8 @@ static struct clkdm_dep gfx_sgx_wkdeps[] = {
 
 /* 24XX-specific possible dependencies */
 
+#ifdef CONFIG_ARCH_OMAP2
+
 /* Wakeup dependency source arrays */
 
 /* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */
@@ -168,6 +170,7 @@ static struct clkdm_dep core_24xx_wkdeps[] = {
 	{ NULL },
 };
 
+#endif /* CONFIG_ARCH_OMAP2 */
 
 /* 2430-specific possible wakeup dependencies */
 
@@ -854,7 +857,12 @@ static struct clockdomain *clockdomains_omap2[] __initdata = {
 	NULL,
 };
 
-void __init omap2_clockdomains_init(void)
+void __init omap2xxx_clockdomains_init(void)
+{
+	clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations);
+}
+
+void __init omap3xxx_clockdomains_init(void)
 {
-	clkdm_init(clockdomains_omap2, clkdm_autodeps);
+	clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap3_clkdm_operations);
 }

+ 388 - 8
arch/arm/mach-omap2/clockdomains44xx_data.c

@@ -18,11 +18,6 @@
  * published by the Free Software Foundation.
  */
 
-/*
- * To-Do List
- * -> Populate the Sleep/Wakeup dependencies for the domains
- */
-
 #include <linux/kernel.h>
 #include <linux/io.h>
 
@@ -35,6 +30,355 @@
 #include "prcm44xx.h"
 #include "prcm_mpu44xx.h"
 
+/* Static Dependencies for OMAP4 Clock Domains */
+
+static struct clkdm_dep ducati_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "abe_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_2_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_dss_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_gfx_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_init_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_cfg_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_per_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_secure_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_wkup_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "tesla_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep iss_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep ivahd_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep l3_d2d_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "abe_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_2_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_init_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_cfg_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_per_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep l3_dma_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "abe_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ducati_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_dss_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_init_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_cfg_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_per_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_secure_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_wkup_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep l3_dss_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_2_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep l3_init_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "abe_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_cfg_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_per_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_secure_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_wkup_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep l4_secure_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_per_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep mpuss_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "abe_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ducati_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_2_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_dss_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_gfx_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_init_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_cfg_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_per_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_secure_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_wkup_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "tesla_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
+
+static struct clkdm_dep tesla_wkup_sleep_deps[] = {
+	{
+		.clkdm_name	 = "abe_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "ivahd_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_1_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_2_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_emif_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l3_init_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_cfg_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_per_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{
+		.clkdm_name	 = "l4_wkup_clkdm",
+		.omap_chip	 = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+	},
+	{ NULL },
+};
 
 static struct clockdomain l4_cefuse_44xx_clkdm = {
 	.name		  = "l4_cefuse_clkdm",
@@ -52,6 +396,7 @@ static struct clockdomain l4_cfg_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CORE_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CORE_L4CFG_CDOFFS,
+	.dep_bit	  = OMAP4430_L4CFG_STATDEP_SHIFT,
 	.flags		  = CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -62,6 +407,9 @@ static struct clockdomain tesla_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM1_PARTITION,
 	.cm_inst	  = OMAP4430_CM1_TESLA_INST,
 	.clkdm_offs	  = OMAP4430_CM1_TESLA_TESLA_CDOFFS,
+	.dep_bit	  = OMAP4430_TESLA_STATDEP_SHIFT,
+	.wkdep_srcs	  = tesla_wkup_sleep_deps,
+	.sleepdep_srcs	  = tesla_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -72,6 +420,9 @@ static struct clockdomain l3_gfx_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_GFX_INST,
 	.clkdm_offs	  = OMAP4430_CM2_GFX_GFX_CDOFFS,
+	.dep_bit	  = OMAP4430_GFX_STATDEP_SHIFT,
+	.wkdep_srcs	  = l3_gfx_wkup_sleep_deps,
+	.sleepdep_srcs	  = l3_gfx_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -82,6 +433,9 @@ static struct clockdomain ivahd_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_IVAHD_INST,
 	.clkdm_offs	  = OMAP4430_CM2_IVAHD_IVAHD_CDOFFS,
+	.dep_bit	  = OMAP4430_IVAHD_STATDEP_SHIFT,
+	.wkdep_srcs	  = ivahd_wkup_sleep_deps,
+	.sleepdep_srcs	  = ivahd_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -92,6 +446,9 @@ static struct clockdomain l4_secure_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_L4PER_INST,
 	.clkdm_offs	  = OMAP4430_CM2_L4PER_L4SEC_CDOFFS,
+	.dep_bit	  = OMAP4430_L4SEC_STATDEP_SHIFT,
+	.wkdep_srcs	  = l4_secure_wkup_sleep_deps,
+	.sleepdep_srcs	  = l4_secure_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -102,6 +459,7 @@ static struct clockdomain l4_per_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_L4PER_INST,
 	.clkdm_offs	  = OMAP4430_CM2_L4PER_L4PER_CDOFFS,
+	.dep_bit	  = OMAP4430_L4PER_STATDEP_SHIFT,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -112,6 +470,7 @@ static struct clockdomain abe_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM1_PARTITION,
 	.cm_inst	  = OMAP4430_CM1_ABE_INST,
 	.clkdm_offs	  = OMAP4430_CM1_ABE_ABE_CDOFFS,
+	.dep_bit	  = OMAP4430_ABE_STATDEP_SHIFT,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -131,6 +490,9 @@ static struct clockdomain l3_init_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_L3INIT_INST,
 	.clkdm_offs	  = OMAP4430_CM2_L3INIT_L3INIT_CDOFFS,
+	.dep_bit	  = OMAP4430_L3INIT_STATDEP_SHIFT,
+	.wkdep_srcs	  = l3_init_wkup_sleep_deps,
+	.sleepdep_srcs	  = l3_init_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -141,6 +503,8 @@ static struct clockdomain mpuss_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM1_PARTITION,
 	.cm_inst	  = OMAP4430_CM1_MPU_INST,
 	.clkdm_offs	  = OMAP4430_CM1_MPU_MPU_CDOFFS,
+	.wkdep_srcs	  = mpuss_wkup_sleep_deps,
+	.sleepdep_srcs	  = mpuss_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -150,7 +514,7 @@ static struct clockdomain mpu0_44xx_clkdm = {
 	.pwrdm		  = { .name = "cpu0_pwrdm" },
 	.prcm_partition	  = OMAP4430_PRCM_MPU_PARTITION,
 	.cm_inst	  = OMAP4430_PRCM_MPU_CPU0_INST,
-	.clkdm_offs	  = OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS,
+	.clkdm_offs	  = OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS,
 	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -160,7 +524,7 @@ static struct clockdomain mpu1_44xx_clkdm = {
 	.pwrdm		  = { .name = "cpu1_pwrdm" },
 	.prcm_partition	  = OMAP4430_PRCM_MPU_PARTITION,
 	.cm_inst	  = OMAP4430_PRCM_MPU_CPU1_INST,
-	.clkdm_offs	  = OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS,
+	.clkdm_offs	  = OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS,
 	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -171,6 +535,7 @@ static struct clockdomain l3_emif_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CORE_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CORE_MEMIF_CDOFFS,
+	.dep_bit	  = OMAP4430_MEMIF_STATDEP_SHIFT,
 	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -191,6 +556,9 @@ static struct clockdomain ducati_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CORE_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CORE_DUCATI_CDOFFS,
+	.dep_bit	  = OMAP4430_DUCATI_STATDEP_SHIFT,
+	.wkdep_srcs	  = ducati_wkup_sleep_deps,
+	.sleepdep_srcs	  = ducati_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -201,6 +569,7 @@ static struct clockdomain l3_2_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CORE_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CORE_L3_2_CDOFFS,
+	.dep_bit	  = OMAP4430_L3_2_STATDEP_SHIFT,
 	.flags		  = CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -211,6 +580,7 @@ static struct clockdomain l3_1_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CORE_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CORE_L3_1_CDOFFS,
+	.dep_bit	  = OMAP4430_L3_1_STATDEP_SHIFT,
 	.flags		  = CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -221,6 +591,8 @@ static struct clockdomain l3_d2d_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CORE_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CORE_D2D_CDOFFS,
+	.wkdep_srcs	  = l3_d2d_wkup_sleep_deps,
+	.sleepdep_srcs	  = l3_d2d_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -231,6 +603,8 @@ static struct clockdomain iss_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CAM_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CAM_CAM_CDOFFS,
+	.wkdep_srcs	  = iss_wkup_sleep_deps,
+	.sleepdep_srcs	  = iss_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -241,6 +615,9 @@ static struct clockdomain l3_dss_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_DSS_INST,
 	.clkdm_offs	  = OMAP4430_CM2_DSS_DSS_CDOFFS,
+	.dep_bit	  = OMAP4430_DSS_STATDEP_SHIFT,
+	.wkdep_srcs	  = l3_dss_wkup_sleep_deps,
+	.sleepdep_srcs	  = l3_dss_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -251,6 +628,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_WKUP_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS,
+	.dep_bit	  = OMAP4430_L4WKUP_STATDEP_SHIFT,
 	.flags		  = CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -271,6 +649,8 @@ static struct clockdomain l3_dma_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_CM2_PARTITION,
 	.cm_inst	  = OMAP4430_CM2_CORE_INST,
 	.clkdm_offs	  = OMAP4430_CM2_CORE_SDMA_CDOFFS,
+	.wkdep_srcs	  = l3_dma_wkup_sleep_deps,
+	.sleepdep_srcs	  = l3_dma_wkup_sleep_deps,
 	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
@@ -305,5 +685,5 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = {
 
 void __init omap44xx_clockdomains_init(void)
 {
-	clkdm_init(clockdomains_omap44xx, NULL);
+	clkdm_init(clockdomains_omap44xx, NULL, &omap4_clkdm_operations);
 }

+ 3 - 0
arch/arm/mach-omap2/cm-regbits-24xx.h

@@ -210,8 +210,11 @@
 #define OMAP24XX_AUTO_USB_MASK				(1 << 0)
 
 /* CM_AUTOIDLE3_CORE */
+#define OMAP24XX_AUTO_SDRC_SHIFT			2
 #define OMAP24XX_AUTO_SDRC_MASK				(1 << 2)
+#define OMAP24XX_AUTO_GPMC_SHIFT			1
 #define OMAP24XX_AUTO_GPMC_MASK				(1 << 1)
+#define OMAP24XX_AUTO_SDMA_SHIFT			0
 #define OMAP24XX_AUTO_SDMA_MASK				(1 << 0)
 
 /* CM_AUTOIDLE4_CORE */

+ 69 - 0
arch/arm/mach-omap2/cm2xxx_3xxx.c

@@ -25,6 +25,14 @@
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
 
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
+#define DPLL_AUTOIDLE_DISABLE				0x0
+#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP		0x3
+
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
+#define OMAP2XXX_APLL_AUTOIDLE_DISABLE			0x0
+#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP		0x3
+
 static const u8 cm_idlest_offs[] = {
 	CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
 };
@@ -125,6 +133,67 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
 	_write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
 }
 
+/*
+ * DPLL autoidle control
+ */
+
+static void _omap2xxx_set_dpll_autoidle(u8 m)
+{
+	u32 v;
+
+	v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+	v &= ~OMAP24XX_AUTO_DPLL_MASK;
+	v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
+	omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_dpll_disable_autoidle(void)
+{
+	_omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
+}
+
+void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
+{
+	_omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
+}
+
+/*
+ * APLL autoidle control
+ */
+
+static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
+{
+	u32 v;
+
+	v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+	v &= ~mask;
+	v |= m << __ffs(mask);
+	omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_apll54_disable_autoidle(void)
+{
+	_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+				    OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
+{
+	_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+				    OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_disable_autoidle(void)
+{
+	_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+				    OMAP24XX_AUTO_96M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
+{
+	_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+				    OMAP24XX_AUTO_96M_MASK);
+}
 
 /*
  *

+ 8 - 0
arch/arm/mach-omap2/cm2xxx_3xxx.h

@@ -122,6 +122,14 @@ extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
 extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
 extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
 
+extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
+extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
+
+extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
+extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
+
 #endif
 
 /* CM register bits shared between 24XX and 3430 */

+ 1 - 0
arch/arm/mach-omap2/cm44xx.h

@@ -21,6 +21,7 @@
 #include "cm.h"
 
 #define OMAP4_CM_CLKSTCTRL				0x0000
+#define OMAP4_CM_STATICDEP				0x0004
 
 /* Function prototypes */
 # ifndef __ASSEMBLER__

+ 21 - 0
arch/arm/mach-omap2/cminst44xx.c

@@ -73,6 +73,27 @@ u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
 	return v;
 }
 
+u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx)
+{
+	return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx);
+}
+
+u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx)
+{
+	return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx);
+}
+
+u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask)
+{
+	u32 v;
+
+	v = omap4_cminst_read_inst_reg(part, inst, idx);
+	v &= mask;
+	v >>= __ffs(mask);
+
+	return v;
+}
+
 /*
  *
  */

+ 6 - 0
arch/arm/mach-omap2/cminst44xx.h

@@ -25,6 +25,12 @@ extern u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx);
 extern void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
 extern u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
 					   s16 inst, s16 idx);
+extern u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst,
+					   s16 idx);
+extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
+					   s16 idx);
+extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
+					   u32 mask);
 
 extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
 

+ 2 - 2
arch/arm/mach-omap2/cpuidle34xx.c

@@ -100,14 +100,14 @@ static int omap3_idle_bm_check(void)
 static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
 				struct clockdomain *clkdm)
 {
-	omap2_clkdm_allow_idle(clkdm);
+	clkdm_allow_idle(clkdm);
 	return 0;
 }
 
 static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
 				struct clockdomain *clkdm)
 {
-	omap2_clkdm_deny_idle(clkdm);
+	clkdm_deny_idle(clkdm);
 	return 0;
 }
 

+ 84 - 0
arch/arm/mach-omap2/dpll44xx.c

@@ -0,0 +1,84 @@
+/*
+ * OMAP4-specific DPLL control functions
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Rajendra Nayak
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm-regbits-44xx.h"
+
+/* Supported only on OMAP4 */
+int omap4_dpllmx_gatectrl_read(struct clk *clk)
+{
+	u32 v;
+	u32 mask;
+
+	if (!clk || !clk->clksel_reg || !cpu_is_omap44xx())
+		return -EINVAL;
+
+	mask = clk->flags & CLOCK_CLKOUTX2 ?
+			OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+			OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+	v = __raw_readl(clk->clksel_reg);
+	v &= mask;
+	v >>= __ffs(mask);
+
+	return v;
+}
+
+void omap4_dpllmx_allow_gatectrl(struct clk *clk)
+{
+	u32 v;
+	u32 mask;
+
+	if (!clk || !clk->clksel_reg || !cpu_is_omap44xx())
+		return;
+
+	mask = clk->flags & CLOCK_CLKOUTX2 ?
+			OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+			OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+	v = __raw_readl(clk->clksel_reg);
+	/* Clear the bit to allow gatectrl */
+	v &= ~mask;
+	__raw_writel(v, clk->clksel_reg);
+}
+
+void omap4_dpllmx_deny_gatectrl(struct clk *clk)
+{
+	u32 v;
+	u32 mask;
+
+	if (!clk || !clk->clksel_reg || !cpu_is_omap44xx())
+		return;
+
+	mask = clk->flags & CLOCK_CLKOUTX2 ?
+			OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+			OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+	v = __raw_readl(clk->clksel_reg);
+	/* Set the bit to deny gatectrl */
+	v |= mask;
+	__raw_writel(v, clk->clksel_reg);
+}
+
+const struct clkops clkops_omap4_dpllmx_ops = {
+	.allow_idle	= omap4_dpllmx_allow_gatectrl,
+	.deny_idle	= omap4_dpllmx_deny_gatectrl,
+};
+

+ 3 - 3
arch/arm/mach-omap2/io.c

@@ -356,15 +356,15 @@ void __init omap2_init_common_infrastructure(void)
 
 	if (cpu_is_omap242x()) {
 		omap2xxx_powerdomains_init();
-		omap2_clockdomains_init();
+		omap2xxx_clockdomains_init();
 		omap2420_hwmod_init();
 	} else if (cpu_is_omap243x()) {
 		omap2xxx_powerdomains_init();
-		omap2_clockdomains_init();
+		omap2xxx_clockdomains_init();
 		omap2430_hwmod_init();
 	} else if (cpu_is_omap34xx()) {
 		omap3xxx_powerdomains_init();
-		omap2_clockdomains_init();
+		omap3xxx_clockdomains_init();
 		omap3xxx_hwmod_init();
 	} else if (cpu_is_omap44xx()) {
 		omap44xx_powerdomains_init();

+ 119 - 38
arch/arm/mach-omap2/omap_hwmod.c

@@ -370,7 +370,7 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 	}
 
 	autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
-	autoidle_mask = (0x3 << autoidle_shift);
+	autoidle_mask = (0x1 << autoidle_shift);
 
 	*v &= ~autoidle_mask;
 	*v |= autoidle << autoidle_shift;
@@ -457,14 +457,18 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
  * will be accessed by a particular initiator (e.g., if a module will
  * be accessed by the IVA, there should be a sleepdep between the IVA
  * initiator and the module).  Only applies to modules in smart-idle
- * mode.  Returns -EINVAL upon error or passes along
- * clkdm_add_sleepdep() value upon success.
+ * mode.  If the clockdomain is marked as not needing autodeps, return
+ * 0 without doing anything.  Otherwise, returns -EINVAL upon error or
+ * passes along clkdm_add_sleepdep() value upon success.
  */
 static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 {
 	if (!oh->_clk)
 		return -EINVAL;
 
+	if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+		return 0;
+
 	return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
 }
 
@@ -477,14 +481,18 @@ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
  * be accessed by a particular initiator (e.g., if a module will not
  * be accessed by the IVA, there should be no sleepdep between the IVA
  * initiator and the module).  Only applies to modules in smart-idle
- * mode.  Returns -EINVAL upon error or passes along
- * clkdm_del_sleepdep() value upon success.
+ * mode.  If the clockdomain is marked as not needing autodeps, return
+ * 0 without doing anything.  Returns -EINVAL upon error or passes
+ * along clkdm_del_sleepdep() value upon success.
  */
 static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 {
 	if (!oh->_clk)
 		return -EINVAL;
 
+	if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+		return 0;
+
 	return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
 }
 
@@ -921,7 +929,7 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)
 	if (!ret)
 		oh->_state = _HWMOD_STATE_CLKS_INITED;
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -967,25 +975,29 @@ static int _wait_target_ready(struct omap_hwmod *oh)
 }
 
 /**
- * _lookup_hardreset - return the register bit shift for this hwmod/reset line
+ * _lookup_hardreset - fill register bit info for this hwmod/reset line
  * @oh: struct omap_hwmod *
  * @name: name of the reset line in the context of this hwmod
+ * @ohri: struct omap_hwmod_rst_info * that this function will fill in
  *
  * Return the bit position of the reset line that match the
  * input name. Return -ENOENT if not found.
  */
-static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name)
+static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name,
+			    struct omap_hwmod_rst_info *ohri)
 {
 	int i;
 
 	for (i = 0; i < oh->rst_lines_cnt; i++) {
 		const char *rst_line = oh->rst_lines[i].name;
 		if (!strcmp(rst_line, name)) {
-			u8 shift = oh->rst_lines[i].rst_shift;
-			pr_debug("omap_hwmod: %s: _lookup_hardreset: %s: %d\n",
-				 oh->name, rst_line, shift);
+			ohri->rst_shift = oh->rst_lines[i].rst_shift;
+			ohri->st_shift = oh->rst_lines[i].st_shift;
+			pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n",
+				 oh->name, __func__, rst_line, ohri->rst_shift,
+				 ohri->st_shift);
 
-			return shift;
+			return 0;
 		}
 	}
 
@@ -1004,21 +1016,22 @@ static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name)
  */
 static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
 {
-	u8 shift;
+	struct omap_hwmod_rst_info ohri;
+	u8 ret;
 
 	if (!oh)
 		return -EINVAL;
 
-	shift = _lookup_hardreset(oh, name);
-	if (IS_ERR_VALUE(shift))
-		return shift;
+	ret = _lookup_hardreset(oh, name, &ohri);
+	if (IS_ERR_VALUE(ret))
+		return ret;
 
 	if (cpu_is_omap24xx() || cpu_is_omap34xx())
 		return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
-						  shift);
+						  ohri.rst_shift);
 	else if (cpu_is_omap44xx())
 		return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
-						  shift);
+						  ohri.rst_shift);
 	else
 		return -EINVAL;
 }
@@ -1035,29 +1048,34 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
  */
 static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
 {
-	u8 shift;
-	int r;
+	struct omap_hwmod_rst_info ohri;
+	int ret;
 
 	if (!oh)
 		return -EINVAL;
 
-	shift = _lookup_hardreset(oh, name);
-	if (IS_ERR_VALUE(shift))
-		return shift;
+	ret = _lookup_hardreset(oh, name, &ohri);
+	if (IS_ERR_VALUE(ret))
+		return ret;
 
-	if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		r = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
-						 shift);
-	else if (cpu_is_omap44xx())
-		r = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
-						 shift);
-	else
+	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+		ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
+						   ohri.rst_shift,
+						   ohri.st_shift);
+	} else if (cpu_is_omap44xx()) {
+		if (ohri.st_shift)
+			pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
+			       oh->name, name);
+		ret = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
+						   ohri.rst_shift);
+	} else {
 		return -EINVAL;
+	}
 
-	if (r == -EBUSY)
+	if (ret == -EBUSY)
 		pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
 
-	return r;
+	return ret;
 }
 
 /**
@@ -1070,21 +1088,22 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
  */
 static int _read_hardreset(struct omap_hwmod *oh, const char *name)
 {
-	u8 shift;
+	struct omap_hwmod_rst_info ohri;
+	u8 ret;
 
 	if (!oh)
 		return -EINVAL;
 
-	shift = _lookup_hardreset(oh, name);
-	if (IS_ERR_VALUE(shift))
-		return shift;
+	ret = _lookup_hardreset(oh, name, &ohri);
+	if (IS_ERR_VALUE(ret))
+		return ret;
 
 	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
 		return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
-						       shift);
+						       ohri.st_shift);
 	} else if (cpu_is_omap44xx()) {
 		return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
-						       shift);
+						       ohri.rst_shift);
 	} else {
 		return -EINVAL;
 	}
@@ -1282,6 +1301,42 @@ static int _idle(struct omap_hwmod *oh)
 	return 0;
 }
 
+/**
+ * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit
+ * @oh: struct omap_hwmod *
+ * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
+ *
+ * Sets the IP block's OCP autoidle bit in hardware, and updates our
+ * local copy. Intended to be used by drivers that require
+ * direct manipulation of the AUTOIDLE bits.
+ * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes
+ * along the return value from _set_module_autoidle().
+ *
+ * Any users of this function should be scrutinized carefully.
+ */
+int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle)
+{
+	u32 v;
+	int retval = 0;
+	unsigned long flags;
+
+	if (!oh || oh->_state != _HWMOD_STATE_ENABLED)
+		return -EINVAL;
+
+	spin_lock_irqsave(&oh->_lock, flags);
+
+	v = oh->_sysc_cache;
+
+	retval = _set_module_autoidle(oh, autoidle, &v);
+
+	if (!retval)
+		_write_sysconfig(v, oh);
+
+	spin_unlock_irqrestore(&oh->_lock, flags);
+
+	return retval;
+}
+
 /**
  * _shutdown - shutdown an omap_hwmod
  * @oh: struct omap_hwmod *
@@ -2286,3 +2341,29 @@ u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
 
 	return ret;
 }
+
+/**
+ * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup
+ * @oh: struct omap_hwmod *
+ *
+ * Prevent the hwmod @oh from being reset during the setup process.
+ * Intended for use by board-*.c files on boards with devices that
+ * cannot tolerate being reset.  Must be called before the hwmod has
+ * been set up.  Returns 0 upon success or negative error code upon
+ * failure.
+ */
+int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
+{
+	if (!oh)
+		return -EINVAL;
+
+	if (oh->_state != _HWMOD_STATE_REGISTERED) {
+		pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n",
+			oh->name);
+		return -EINVAL;
+	}
+
+	oh->flags |= HWMOD_INIT_NO_RESET;
+
+	return 0;
+}

+ 6 - 5
arch/arm/mach-omap2/omap_hwmod_2420_data.c

@@ -988,7 +988,7 @@ static struct omap_hwmod_class_sysconfig omap2420_wd_timer_sysc = {
 	.sysc_offs	= 0x0010,
 	.syss_offs	= 0x0014,
 	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
@@ -1029,7 +1029,7 @@ static struct omap_hwmod_class_sysconfig uart_sysc = {
 	.syss_offs	= 0x58,
 	.sysc_flags	= (SYSC_HAS_SIDLEMODE |
 			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -1441,7 +1441,7 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = {
 	.rev_offs	= 0x00,
 	.sysc_offs	= 0x20,
 	.syss_offs	= 0x10,
-	.sysc_flags	= SYSC_HAS_SOFTRESET,
+	.sysc_flags	= (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
 	.sysc_fields	= &omap_hwmod_sysc_type1,
 };
 
@@ -1613,7 +1613,8 @@ static struct omap_hwmod_class_sysconfig omap242x_gpio_sysc = {
 	.sysc_offs	= 0x0010,
 	.syss_offs	= 0x0014,
 	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
-			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+			   SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -1755,7 +1756,7 @@ static struct omap_hwmod_class_sysconfig omap2420_dma_sysc = {
 	.syss_offs	= 0x0028,
 	.sysc_flags	= (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE |
 			   SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
 	.sysc_fields	= &omap_hwmod_sysc_type1,
 };

+ 7 - 5
arch/arm/mach-omap2/omap_hwmod_2430_data.c

@@ -1088,7 +1088,7 @@ static struct omap_hwmod_class_sysconfig omap2430_wd_timer_sysc = {
 	.sysc_offs	= 0x0010,
 	.syss_offs	= 0x0014,
 	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
@@ -1129,7 +1129,7 @@ static struct omap_hwmod_class_sysconfig uart_sysc = {
 	.syss_offs	= 0x58,
 	.sysc_flags	= (SYSC_HAS_SIDLEMODE |
 			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -1516,7 +1516,8 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = {
 	.rev_offs	= 0x00,
 	.sysc_offs	= 0x20,
 	.syss_offs	= 0x10,
-	.sysc_flags	= (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.sysc_flags	= (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+			   SYSS_HAS_RESET_STATUS),
 	.sysc_fields	= &omap_hwmod_sysc_type1,
 };
 
@@ -1714,7 +1715,8 @@ static struct omap_hwmod_class_sysconfig omap243x_gpio_sysc = {
 	.sysc_offs	= 0x0010,
 	.syss_offs	= 0x0014,
 	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
-			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+			   SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -1886,7 +1888,7 @@ static struct omap_hwmod_class_sysconfig omap2430_dma_sysc = {
 	.syss_offs	= 0x0028,
 	.sysc_flags	= (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE |
 			   SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
 	.sysc_fields	= &omap_hwmod_sysc_type1,
 };

+ 13 - 34
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c

@@ -23,7 +23,6 @@
 #include <plat/i2c.h>
 #include <plat/gpio.h>
 #include <plat/mmc.h>
-#include <plat/smartreflex.h>
 #include <plat/mcbsp.h>
 #include <plat/mcspi.h>
 #include <plat/dmtimer.h>
@@ -491,26 +490,12 @@ static struct omap_hwmod_ocp_if *am35xx_usbhsotg_slaves[] = {
 /* Slave interfaces on the L4_CORE interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
 	&omap3xxx_l3_main__l4_core,
-	&omap3_l4_core__sr1,
-	&omap3_l4_core__sr2,
-};
-
-/* Master interfaces on the L4_CORE interconnect */
-static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
-	&omap3xxx_l4_core__l4_wkup,
-	&omap3_l4_core__uart1,
-	&omap3_l4_core__uart2,
-	&omap3_l4_core__i2c1,
-	&omap3_l4_core__i2c2,
-	&omap3_l4_core__i2c3,
 };
 
 /* L4 CORE */
 static struct omap_hwmod omap3xxx_l4_core_hwmod = {
 	.name		= "l4_core",
 	.class		= &l4_hwmod_class,
-	.masters	= omap3xxx_l4_core_masters,
-	.masters_cnt	= ARRAY_SIZE(omap3xxx_l4_core_masters),
 	.slaves		= omap3xxx_l4_core_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap3xxx_l4_core_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -522,18 +507,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
 	&omap3xxx_l3_main__l4_per,
 };
 
-/* Master interfaces on the L4_PER interconnect */
-static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
-	&omap3_l4_per__uart3,
-	&omap3_l4_per__uart4,
-};
-
 /* L4 PER */
 static struct omap_hwmod omap3xxx_l4_per_hwmod = {
 	.name		= "l4_per",
 	.class		= &l4_hwmod_class,
-	.masters	= omap3xxx_l4_per_masters,
-	.masters_cnt	= ARRAY_SIZE(omap3xxx_l4_per_masters),
 	.slaves		= omap3xxx_l4_per_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap3xxx_l4_per_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -545,16 +522,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_slaves[] = {
 	&omap3xxx_l4_core__l4_wkup,
 };
 
-/* Master interfaces on the L4_WKUP interconnect */
-static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
-};
-
 /* L4 WKUP */
 static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
 	.name		= "l4_wkup",
 	.class		= &l4_hwmod_class,
-	.masters	= omap3xxx_l4_wkup_masters,
-	.masters_cnt	= ARRAY_SIZE(omap3xxx_l4_wkup_masters),
 	.slaves		= omap3xxx_l4_wkup_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -1268,7 +1239,8 @@ static struct omap_hwmod_class_sysconfig omap3xxx_wd_timer_sysc = {
 	.syss_offs	= 0x0014,
 	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE |
 			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
-			   SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY),
+			   SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -1280,7 +1252,7 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = {
 	.syss_offs	= 0x10,
 	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
 			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -1312,6 +1284,11 @@ static struct omap_hwmod omap3xxx_wd_timer2_hwmod = {
 	.slaves		= omap3xxx_wd_timer2_slaves,
 	.slaves_cnt	= ARRAY_SIZE(omap3xxx_wd_timer2_slaves),
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	/*
+	 * XXX: Use software supervised mode, HW supervised smartidle seems to
+	 * block CORE power domain idle transitions. Maybe a HW bug in wdt2?
+	 */
+	.flags		= HWMOD_SWSUP_SIDLE,
 };
 
 /* UART common */
@@ -1322,7 +1299,7 @@ static struct omap_hwmod_class_sysconfig uart_sysc = {
 	.syss_offs	= 0x58,
 	.sysc_flags	= (SYSC_HAS_SIDLEMODE |
 			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
-			   SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -2128,7 +2105,8 @@ static struct omap_hwmod_class_sysconfig omap3xxx_gpio_sysc = {
 	.sysc_offs	= 0x0010,
 	.syss_offs	= 0x0014,
 	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
-			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+			   SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields    = &omap_hwmod_sysc_type1,
 };
@@ -2382,7 +2360,8 @@ static struct omap_hwmod_class_sysconfig omap3xxx_dma_sysc = {
 	.syss_offs	= 0x0028,
 	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
 			   SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
-			   SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE |
+			   SYSS_HAS_RESET_STATUS),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
 			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
 	.sysc_fields	= &omap_hwmod_sysc_type1,

+ 24 - 0
arch/arm/mach-omap2/omap_opp_data.h

@@ -21,6 +21,8 @@
 
 #include <plat/omap_hwmod.h>
 
+#include "voltage.h"
+
 /*
  * *BIG FAT WARNING*:
  * USE the following ONLY in opp data initialization common to an SoC.
@@ -65,8 +67,30 @@ struct omap_opp_def {
 	.u_volt		= _uv,					\
 }
 
+/*
+ * Initialization wrapper used to define SmartReflex process data
+ * XXX Is this needed?  Just use C99 initializers in data files?
+ */
+#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain)  \
+{								       \
+	.volt_nominal	= _v_nom,				       \
+	.sr_efuse_offs	= _efuse_offs,				       \
+	.sr_errminlimit = _errminlimit,				       \
+	.vp_errgain	= _errgain				       \
+}
+
 /* Use this to initialize the default table */
 extern int __init omap_init_opp_table(struct omap_opp_def *opp_def,
 		u32 opp_def_size);
 
+
+extern struct omap_volt_data omap34xx_vddmpu_volt_data[];
+extern struct omap_volt_data omap34xx_vddcore_volt_data[];
+extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
+extern struct omap_volt_data omap36xx_vddcore_volt_data[];
+
+extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
+extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
+
 #endif		/* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */

+ 1 - 1
arch/arm/mach-omap2/omap_twl.c

@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c/twl.h>
 
-#include <plat/voltage.h>
+#include "voltage.h"
 
 #include "pm.h"
 

+ 65 - 1
arch/arm/mach-omap2/opp3xxx_data.c

@@ -4,8 +4,9 @@
  * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
  *	Nishanth Menon
  *	Kevin Hilman
- * Copyright (C) 2010 Nokia Corporation.
+ * Copyright (C) 2010-2011 Nokia Corporation.
  *      Eduardo Valentin
+ *      Paul Walmsley
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -20,9 +21,72 @@
 
 #include <plat/cpu.h>
 
+#include "control.h"
 #include "omap_opp_data.h"
 #include "pm.h"
 
+/* 34xx */
+
+/* VDD1 */
+
+#define OMAP3430_VDD_MPU_OPP1_UV		975000
+#define OMAP3430_VDD_MPU_OPP2_UV		1075000
+#define OMAP3430_VDD_MPU_OPP3_UV		1200000
+#define OMAP3430_VDD_MPU_OPP4_UV		1270000
+#define OMAP3430_VDD_MPU_OPP5_UV		1350000
+
+struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
+	VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
+	VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* VDD2 */
+
+#define OMAP3430_VDD_CORE_OPP1_UV		975000
+#define OMAP3430_VDD_CORE_OPP2_UV		1050000
+#define OMAP3430_VDD_CORE_OPP3_UV		1150000
+
+struct omap_volt_data omap34xx_vddcore_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* 36xx */
+
+/* VDD1 */
+
+#define OMAP3630_VDD_MPU_OPP50_UV		1012500
+#define OMAP3630_VDD_MPU_OPP100_UV		1200000
+#define OMAP3630_VDD_MPU_OPP120_UV		1325000
+#define OMAP3630_VDD_MPU_OPP1G_UV		1375000
+
+struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* VDD2 */
+
+#define OMAP3630_VDD_CORE_OPP50_UV		1000000
+#define OMAP3630_VDD_CORE_OPP100_UV		1200000
+
+struct omap_volt_data omap36xx_vddcore_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* OPP data */
+
 static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
 	/* MPU OPP1 */
 	OPP_INITIALIZER("mpu", true, 125000000, 975000),

+ 42 - 1
arch/arm/mach-omap2/opp4xxx_data.c

@@ -5,8 +5,9 @@
  *	Nishanth Menon
  *	Kevin Hilman
  *	Thara Gopinath
- * Copyright (C) 2010 Nokia Corporation.
+ * Copyright (C) 2010-2011 Nokia Corporation.
  *      Eduardo Valentin
+ *      Paul Walmsley
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -21,9 +22,49 @@
 
 #include <plat/cpu.h>
 
+#include "control.h"
 #include "omap_opp_data.h"
 #include "pm.h"
 
+/*
+ * Structures containing OMAP4430 voltage supported and various
+ * voltage dependent data for each VDD.
+ */
+
+#define OMAP4430_VDD_MPU_OPP50_UV		930000
+#define OMAP4430_VDD_MPU_OPP100_UV		1100000
+#define OMAP4430_VDD_MPU_OPPTURBO_UV		1260000
+#define OMAP4430_VDD_MPU_OPPNITRO_UV		1350000
+
+struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4430_VDD_IVA_OPP50_UV		930000
+#define OMAP4430_VDD_IVA_OPP100_UV		1100000
+#define OMAP4430_VDD_IVA_OPPTURBO_UV		1260000
+
+struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4430_VDD_CORE_OPP50_UV		930000
+#define OMAP4430_VDD_CORE_OPP100_UV		1100000
+
+struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+
 static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
 	/* MPU OPP1 - OPP50 */
 	OPP_INITIALIZER("mpu", true, 300000000, 1100000),

+ 4 - 4
arch/arm/mach-omap2/pm.c

@@ -18,8 +18,8 @@
 #include <plat/omap-pm.h>
 #include <plat/omap_device.h>
 #include <plat/common.h>
-#include <plat/voltage.h>
 
+#include "voltage.h"
 #include "powerdomain.h"
 #include "clockdomain.h"
 #include "pm.h"
@@ -126,7 +126,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
 			(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
 			sleep_switch = LOWPOWERSTATE_SWITCH;
 		} else {
-			omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+			clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
 			pwrdm_wait_transition(pwrdm);
 			sleep_switch = FORCEWAKEUP_SWITCH;
 		}
@@ -142,9 +142,9 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
 	switch (sleep_switch) {
 	case FORCEWAKEUP_SWITCH:
 		if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
-			omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+			clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
 		else
-			omap2_clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+			clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
 		break;
 	case LOWPOWERSTATE_SWITCH:
 		pwrdm_set_lowpwrstchange(pwrdm);

+ 8 - 69
arch/arm/mach-omap2/pm24xx.c

@@ -364,10 +364,10 @@ static const struct platform_suspend_ops __initdata omap_pm_ops;
 static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
 	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
-		omap2_clkdm_allow_idle(clkdm);
+		clkdm_allow_idle(clkdm);
 	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
 		 atomic_read(&clkdm->usecount) == 0)
-		omap2_clkdm_sleep(clkdm);
+		clkdm_sleep(clkdm);
 	return 0;
 }
 
@@ -376,7 +376,10 @@ static void __init prcm_setup_regs(void)
 	int i, num_mem_banks;
 	struct powerdomain *pwrdm;
 
-	/* Enable autoidle */
+	/*
+	 * Enable autoidle
+	 * XXX This should be handled by hwmod code or PRCM init code
+	 */
 	omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD,
 			  OMAP2_PRCM_SYSCONFIG_OFFSET);
 
@@ -402,80 +405,16 @@ static void __init prcm_setup_regs(void)
 
 	pwrdm = clkdm_get_pwrdm(dsp_clkdm);
 	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
-	omap2_clkdm_sleep(dsp_clkdm);
+	clkdm_sleep(dsp_clkdm);
 
 	pwrdm = clkdm_get_pwrdm(gfx_clkdm);
 	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
-	omap2_clkdm_sleep(gfx_clkdm);
+	clkdm_sleep(gfx_clkdm);
 
 	/* Enable hardware-supervised idle for all clkdms */
 	clkdm_for_each(clkdms_setup, NULL);
 	clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
 
-	/* Enable clock autoidle for all domains */
-	omap2_cm_write_mod_reg(OMAP24XX_AUTO_CAM_MASK |
-			       OMAP24XX_AUTO_MAILBOXES_MASK |
-			       OMAP24XX_AUTO_WDT4_MASK |
-			       OMAP2420_AUTO_WDT3_MASK |
-			       OMAP24XX_AUTO_MSPRO_MASK |
-			       OMAP2420_AUTO_MMC_MASK |
-			       OMAP24XX_AUTO_FAC_MASK |
-			       OMAP2420_AUTO_EAC_MASK |
-			       OMAP24XX_AUTO_HDQ_MASK |
-			       OMAP24XX_AUTO_UART2_MASK |
-			       OMAP24XX_AUTO_UART1_MASK |
-			       OMAP24XX_AUTO_I2C2_MASK |
-			       OMAP24XX_AUTO_I2C1_MASK |
-			       OMAP24XX_AUTO_MCSPI2_MASK |
-			       OMAP24XX_AUTO_MCSPI1_MASK |
-			       OMAP24XX_AUTO_MCBSP2_MASK |
-			       OMAP24XX_AUTO_MCBSP1_MASK |
-			       OMAP24XX_AUTO_GPT12_MASK |
-			       OMAP24XX_AUTO_GPT11_MASK |
-			       OMAP24XX_AUTO_GPT10_MASK |
-			       OMAP24XX_AUTO_GPT9_MASK |
-			       OMAP24XX_AUTO_GPT8_MASK |
-			       OMAP24XX_AUTO_GPT7_MASK |
-			       OMAP24XX_AUTO_GPT6_MASK |
-			       OMAP24XX_AUTO_GPT5_MASK |
-			       OMAP24XX_AUTO_GPT4_MASK |
-			       OMAP24XX_AUTO_GPT3_MASK |
-			       OMAP24XX_AUTO_GPT2_MASK |
-			       OMAP2420_AUTO_VLYNQ_MASK |
-			       OMAP24XX_AUTO_DSS_MASK,
-			       CORE_MOD, CM_AUTOIDLE1);
-	omap2_cm_write_mod_reg(OMAP24XX_AUTO_UART3_MASK |
-			       OMAP24XX_AUTO_SSI_MASK |
-			       OMAP24XX_AUTO_USB_MASK,
-			       CORE_MOD, CM_AUTOIDLE2);
-	omap2_cm_write_mod_reg(OMAP24XX_AUTO_SDRC_MASK |
-			       OMAP24XX_AUTO_GPMC_MASK |
-			       OMAP24XX_AUTO_SDMA_MASK,
-			       CORE_MOD, CM_AUTOIDLE3);
-	omap2_cm_write_mod_reg(OMAP24XX_AUTO_PKA_MASK |
-			       OMAP24XX_AUTO_AES_MASK |
-			       OMAP24XX_AUTO_RNG_MASK |
-			       OMAP24XX_AUTO_SHA_MASK |
-			       OMAP24XX_AUTO_DES_MASK,
-			       CORE_MOD, OMAP24XX_CM_AUTOIDLE4);
-
-	omap2_cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD,
-			       CM_AUTOIDLE);
-
-	/* Put DPLL and both APLLs into autoidle mode */
-	omap2_cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
-			       (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
-			       (0x03 << OMAP24XX_AUTO_54M_SHIFT),
-			       PLL_MOD, CM_AUTOIDLE);
-
-	omap2_cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK |
-			       OMAP24XX_AUTO_WDT1_MASK |
-			       OMAP24XX_AUTO_MPU_WDT_MASK |
-			       OMAP24XX_AUTO_GPIOS_MASK |
-			       OMAP24XX_AUTO_32KSYNC_MASK |
-			       OMAP24XX_AUTO_GPT1_MASK,
-			       WKUP_MOD, CM_AUTOIDLE);
-
 	/* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
 	 * stabilisation */
 	omap2_prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,

+ 4 - 123
arch/arm/mach-omap2/pm34xx.c

@@ -491,7 +491,7 @@ console_still_active:
 
 	pwrdm_post_transition();
 
-	omap2_clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
+	clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
 
 int omap3_can_sleep(void)
@@ -683,133 +683,14 @@ static void __init omap3_d2d_idle(void)
 
 static void __init prcm_setup_regs(void)
 {
-	u32 omap3630_auto_uart4_mask = cpu_is_omap3630() ?
-					OMAP3630_AUTO_UART4_MASK : 0;
 	u32 omap3630_en_uart4_mask = cpu_is_omap3630() ?
 					OMAP3630_EN_UART4_MASK : 0;
 	u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ?
 					OMAP3630_GRPSEL_UART4_MASK : 0;
 
-	/*
-	 * Enable interface clock autoidle for all modules.
-	 * Note that in the long run this should be done by clockfw
-	 */
-	omap2_cm_write_mod_reg(
-		OMAP3430_AUTO_MODEM_MASK |
-		OMAP3430ES2_AUTO_MMC3_MASK |
-		OMAP3430ES2_AUTO_ICR_MASK |
-		OMAP3430_AUTO_AES2_MASK |
-		OMAP3430_AUTO_SHA12_MASK |
-		OMAP3430_AUTO_DES2_MASK |
-		OMAP3430_AUTO_MMC2_MASK |
-		OMAP3430_AUTO_MMC1_MASK |
-		OMAP3430_AUTO_MSPRO_MASK |
-		OMAP3430_AUTO_HDQ_MASK |
-		OMAP3430_AUTO_MCSPI4_MASK |
-		OMAP3430_AUTO_MCSPI3_MASK |
-		OMAP3430_AUTO_MCSPI2_MASK |
-		OMAP3430_AUTO_MCSPI1_MASK |
-		OMAP3430_AUTO_I2C3_MASK |
-		OMAP3430_AUTO_I2C2_MASK |
-		OMAP3430_AUTO_I2C1_MASK |
-		OMAP3430_AUTO_UART2_MASK |
-		OMAP3430_AUTO_UART1_MASK |
-		OMAP3430_AUTO_GPT11_MASK |
-		OMAP3430_AUTO_GPT10_MASK |
-		OMAP3430_AUTO_MCBSP5_MASK |
-		OMAP3430_AUTO_MCBSP1_MASK |
-		OMAP3430ES1_AUTO_FAC_MASK | /* This is es1 only */
-		OMAP3430_AUTO_MAILBOXES_MASK |
-		OMAP3430_AUTO_OMAPCTRL_MASK |
-		OMAP3430ES1_AUTO_FSHOSTUSB_MASK |
-		OMAP3430_AUTO_HSOTGUSB_MASK |
-		OMAP3430_AUTO_SAD2D_MASK |
-		OMAP3430_AUTO_SSI_MASK,
-		CORE_MOD, CM_AUTOIDLE1);
-
-	omap2_cm_write_mod_reg(
-		OMAP3430_AUTO_PKA_MASK |
-		OMAP3430_AUTO_AES1_MASK |
-		OMAP3430_AUTO_RNG_MASK |
-		OMAP3430_AUTO_SHA11_MASK |
-		OMAP3430_AUTO_DES1_MASK,
-		CORE_MOD, CM_AUTOIDLE2);
-
-	if (omap_rev() > OMAP3430_REV_ES1_0) {
-		omap2_cm_write_mod_reg(
-			OMAP3430_AUTO_MAD2D_MASK |
-			OMAP3430ES2_AUTO_USBTLL_MASK,
-			CORE_MOD, CM_AUTOIDLE3);
-	}
-
-	omap2_cm_write_mod_reg(
-		OMAP3430_AUTO_WDT2_MASK |
-		OMAP3430_AUTO_WDT1_MASK |
-		OMAP3430_AUTO_GPIO1_MASK |
-		OMAP3430_AUTO_32KSYNC_MASK |
-		OMAP3430_AUTO_GPT12_MASK |
-		OMAP3430_AUTO_GPT1_MASK,
-		WKUP_MOD, CM_AUTOIDLE);
-
-	omap2_cm_write_mod_reg(
-		OMAP3430_AUTO_DSS_MASK,
-		OMAP3430_DSS_MOD,
-		CM_AUTOIDLE);
-
-	omap2_cm_write_mod_reg(
-		OMAP3430_AUTO_CAM_MASK,
-		OMAP3430_CAM_MOD,
-		CM_AUTOIDLE);
-
-	omap2_cm_write_mod_reg(
-		omap3630_auto_uart4_mask |
-		OMAP3430_AUTO_GPIO6_MASK |
-		OMAP3430_AUTO_GPIO5_MASK |
-		OMAP3430_AUTO_GPIO4_MASK |
-		OMAP3430_AUTO_GPIO3_MASK |
-		OMAP3430_AUTO_GPIO2_MASK |
-		OMAP3430_AUTO_WDT3_MASK |
-		OMAP3430_AUTO_UART3_MASK |
-		OMAP3430_AUTO_GPT9_MASK |
-		OMAP3430_AUTO_GPT8_MASK |
-		OMAP3430_AUTO_GPT7_MASK |
-		OMAP3430_AUTO_GPT6_MASK |
-		OMAP3430_AUTO_GPT5_MASK |
-		OMAP3430_AUTO_GPT4_MASK |
-		OMAP3430_AUTO_GPT3_MASK |
-		OMAP3430_AUTO_GPT2_MASK |
-		OMAP3430_AUTO_MCBSP4_MASK |
-		OMAP3430_AUTO_MCBSP3_MASK |
-		OMAP3430_AUTO_MCBSP2_MASK,
-		OMAP3430_PER_MOD,
-		CM_AUTOIDLE);
-
-	if (omap_rev() > OMAP3430_REV_ES1_0) {
-		omap2_cm_write_mod_reg(
-			OMAP3430ES2_AUTO_USBHOST_MASK,
-			OMAP3430ES2_USBHOST_MOD,
-			CM_AUTOIDLE);
-	}
-
+	/* XXX This should be handled by hwmod code or SCM init code */
 	omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG);
 
-	/*
-	 * Set all plls to autoidle. This is needed until autoidle is
-	 * enabled by clockfw
-	 */
-	omap2_cm_write_mod_reg(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
-			 OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
-	omap2_cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
-			 MPU_MOD,
-			 CM_AUTOIDLE2);
-	omap2_cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
-			 (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
-			 PLL_MOD,
-			 CM_AUTOIDLE);
-	omap2_cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
-			 PLL_MOD,
-			 CM_AUTOIDLE2);
-
 	/*
 	 * Enable control of expternal oscillator through
 	 * sys_clkreq. In the long run clock framework should
@@ -969,10 +850,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
 	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
-		omap2_clkdm_allow_idle(clkdm);
+		clkdm_allow_idle(clkdm);
 	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
 		 atomic_read(&clkdm->usecount) == 0)
-		omap2_clkdm_sleep(clkdm);
+		clkdm_sleep(clkdm);
 	return 0;
 }
 

+ 42 - 1
arch/arm/mach-omap2/powerdomain.c

@@ -2,7 +2,7 @@
  * OMAP powerdomain control
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Written by Paul Walmsley
  * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
@@ -938,3 +938,44 @@ u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
 
 	return count;
 }
+
+/**
+ * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
+ * @pwrdm: struct powerdomain *
+ *
+ * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
+ * can lose either memory or logic context or if @pwrdm is invalid, or
+ * returns 0 otherwise.  This function is not concerned with how the
+ * powerdomain registers are programmed (i.e., to go off or not); it's
+ * concerned with whether it's ever possible for this powerdomain to
+ * go off while some other part of the chip is active.  This function
+ * assumes that every powerdomain can go to either ON or INACTIVE.
+ */
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
+{
+	int i;
+
+	if (IS_ERR_OR_NULL(pwrdm)) {
+		pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
+			 __func__);
+		return 1;
+	}
+
+	if (pwrdm->pwrsts & PWRSTS_OFF)
+		return 1;
+
+	if (pwrdm->pwrsts & PWRSTS_RET) {
+		if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
+			return 1;
+
+		for (i = 0; i < pwrdm->banks; i++)
+			if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
+				return 1;
+	}
+
+	for (i = 0; i < pwrdm->banks; i++)
+		if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
+			return 1;
+
+	return 0;
+}

+ 8 - 11
arch/arm/mach-omap2/powerdomain.h

@@ -2,7 +2,7 @@
  * OMAP2/3/4 powerdomain control
  *
  * Copyright (C) 2007-2008, 2010 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Paul Walmsley
  *
@@ -34,17 +34,14 @@
 
 /* Powerdomain allowable state bitfields */
 #define PWRSTS_ON		(1 << PWRDM_POWER_ON)
+#define PWRSTS_INACTIVE		(1 << PWRDM_POWER_INACTIVE)
+#define PWRSTS_RET		(1 << PWRDM_POWER_RET)
 #define PWRSTS_OFF		(1 << PWRDM_POWER_OFF)
-#define PWRSTS_OFF_ON		((1 << PWRDM_POWER_OFF) | \
-				 (1 << PWRDM_POWER_ON))
 
-#define PWRSTS_OFF_RET		((1 << PWRDM_POWER_OFF) | \
-				 (1 << PWRDM_POWER_RET))
-
-#define PWRSTS_RET_ON		((1 << PWRDM_POWER_RET) | \
-				 (1 << PWRDM_POWER_ON))
-
-#define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
+#define PWRSTS_OFF_ON		(PWRSTS_OFF | PWRSTS_ON)
+#define PWRSTS_OFF_RET		(PWRSTS_OFF | PWRSTS_RET)
+#define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
+#define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
 
 
 /* Powerdomain flags */
@@ -165,7 +162,6 @@ struct pwrdm_ops {
 	int	(*pwrdm_wait_transition)(struct powerdomain *pwrdm);
 };
 
-void pwrdm_fw_init(void);
 void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs);
 
 struct powerdomain *pwrdm_lookup(const char *name);
@@ -212,6 +208,7 @@ int pwrdm_pre_transition(void);
 int pwrdm_post_transition(void);
 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
 u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
 
 extern void omap2xxx_powerdomains_init(void);
 extern void omap3xxx_powerdomains_init(void);

+ 5 - 4
arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c

@@ -2,7 +2,7 @@
  * OMAP2/3 common powerdomain definitions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Paul Walmsley, Jouni Högander
  *
@@ -62,13 +62,13 @@ struct powerdomain gfx_omap2_pwrdm = {
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
 					   CHIP_IS_OMAP3430ES1),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+		[0] = PWRSTS_RET, /* MEMRETSTATE */
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
 };
 
@@ -76,4 +76,5 @@ struct powerdomain wkup_omap2_pwrdm = {
 	.name		= "wkup_pwrdm",
 	.prcm_offs	= WKUP_MOD,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+	.pwrsts		= PWRSTS_ON,
 };

+ 9 - 9
arch/arm/mach-omap2/powerdomains2xxx_data.c

@@ -2,7 +2,7 @@
  * OMAP2XXX powerdomain definitions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Paul Walmsley, Jouni Högander
  *
@@ -30,13 +30,13 @@ static struct powerdomain dsp_pwrdm = {
 	.prcm_offs	  = OMAP24XX_DSP_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET,
+		[0] = PWRSTS_RET,
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,
+		[0] = PWRSTS_ON,
 	},
 };
 
@@ -48,10 +48,10 @@ static struct powerdomain mpu_24xx_pwrdm = {
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET,
+		[0] = PWRSTS_RET,
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,
+		[0] = PWRSTS_ON,
 	},
 };
 
@@ -87,13 +87,13 @@ static struct powerdomain mdm_pwrdm = {
 	.prcm_offs	  = OMAP2430_MDM_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+		[0] = PWRSTS_RET, /* MEMRETSTATE */
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
 };
 

+ 19 - 19
arch/arm/mach-omap2/powerdomains3xxx_data.c

@@ -2,7 +2,7 @@
  * OMAP3 powerdomain definitions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
+ * Copyright (C) 2007-2011 Nokia Corporation
  *
  * Paul Walmsley, Jouni Högander
  *
@@ -47,10 +47,10 @@ static struct powerdomain iva2_pwrdm = {
 		[3] = PWRSTS_OFF_RET,
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,
-		[1] = PWRDM_POWER_ON,
+		[0] = PWRSTS_ON,
+		[1] = PWRSTS_ON,
 		[2] = PWRSTS_OFF_ON,
-		[3] = PWRDM_POWER_ON,
+		[3] = PWRSTS_ON,
 	},
 };
 
@@ -128,13 +128,13 @@ static struct powerdomain dss_pwrdm = {
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 	.prcm_offs	  = OMAP3430_DSS_MOD,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+		[0] = PWRSTS_RET, /* MEMRETSTATE */
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
 };
 
@@ -149,13 +149,13 @@ static struct powerdomain sgx_pwrdm = {
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 	/* XXX This is accurate for 3430 SGX, but what about GFX? */
 	.pwrsts		  = PWRSTS_OFF_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+		[0] = PWRSTS_RET, /* MEMRETSTATE */
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
 };
 
@@ -164,13 +164,13 @@ static struct powerdomain cam_pwrdm = {
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 	.prcm_offs	  = OMAP3430_CAM_MOD,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+		[0] = PWRSTS_RET, /* MEMRETSTATE */
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
 };
 
@@ -182,10 +182,10 @@ static struct powerdomain per_pwrdm = {
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+		[0] = PWRSTS_RET, /* MEMRETSTATE */
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
 };
 
@@ -200,7 +200,7 @@ static struct powerdomain neon_pwrdm = {
 	.prcm_offs	  = OMAP3430_NEON_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 };
 
 static struct powerdomain usbhost_pwrdm = {
@@ -208,7 +208,7 @@ static struct powerdomain usbhost_pwrdm = {
 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_RET,
+	.pwrsts_logic_ret = PWRSTS_RET,
 	/*
 	 * REVISIT: Enabling usb host save and restore mechanism seems to
 	 * leave the usb host domain permanently in ACTIVE mode after
@@ -218,10 +218,10 @@ static struct powerdomain usbhost_pwrdm = {
 	/*.flags	  = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
-		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+		[0] = PWRSTS_RET, /* MEMRETSTATE */
 	},
 	.pwrsts_mem_on	  = {
-		[0] = PWRDM_POWER_ON,  /* MEMONSTATE */
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
 };
 

+ 44 - 44
arch/arm/mach-omap2/powerdomains44xx_data.c

@@ -2,7 +2,7 @@
  * OMAP4 Power domains framework
  *
  * Copyright (C) 2009-2010 Texas Instruments, Inc.
- * Copyright (C) 2009-2010 Nokia Corporation
+ * Copyright (C) 2009-2011 Nokia Corporation
  *
  * Abhijit Pagare (abhijitpagare@ti.com)
  * Benoit Cousson (b-cousson@ti.com)
@@ -40,18 +40,18 @@ static struct powerdomain core_44xx_pwrdm = {
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 5,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* core_nret_bank */
+		[0] = PWRSTS_OFF,	/* core_nret_bank */
 		[1] = PWRSTS_OFF_RET,	/* core_ocmram */
-		[2] = PWRDM_POWER_RET,	/* core_other_bank */
+		[2] = PWRSTS_RET,	/* core_other_bank */
 		[3] = PWRSTS_OFF_RET,	/* ducati_l2ram */
 		[4] = PWRSTS_OFF_RET,	/* ducati_unicache */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* core_nret_bank */
+		[0] = PWRSTS_ON,	/* core_nret_bank */
 		[1] = PWRSTS_OFF_RET,	/* core_ocmram */
-		[2] = PWRDM_POWER_ON,	/* core_other_bank */
-		[3] = PWRDM_POWER_ON,	/* ducati_l2ram */
-		[4] = PWRDM_POWER_ON,	/* ducati_unicache */
+		[2] = PWRSTS_ON,	/* core_other_bank */
+		[3] = PWRSTS_ON,	/* ducati_l2ram */
+		[4] = PWRSTS_ON,	/* ducati_unicache */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -65,10 +65,10 @@ static struct powerdomain gfx_44xx_pwrdm = {
 	.pwrsts		  = PWRSTS_OFF_ON,
 	.banks		  = 1,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* gfx_mem */
+		[0] = PWRSTS_OFF,	/* gfx_mem */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* gfx_mem */
+		[0] = PWRSTS_ON,	/* gfx_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -80,15 +80,15 @@ static struct powerdomain abe_44xx_pwrdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_OFF,
+	.pwrsts_logic_ret = PWRSTS_OFF,
 	.banks		  = 2,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_RET,	/* aessmem */
-		[1] = PWRDM_POWER_OFF,	/* periphmem */
+		[0] = PWRSTS_RET,	/* aessmem */
+		[1] = PWRSTS_OFF,	/* periphmem */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* aessmem */
-		[1] = PWRDM_POWER_ON,	/* periphmem */
+		[0] = PWRSTS_ON,	/* aessmem */
+		[1] = PWRSTS_ON,	/* periphmem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -103,10 +103,10 @@ static struct powerdomain dss_44xx_pwrdm = {
 	.pwrsts_logic_ret = PWRSTS_OFF,
 	.banks		  = 1,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* dss_mem */
+		[0] = PWRSTS_OFF,	/* dss_mem */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* dss_mem */
+		[0] = PWRSTS_ON,	/* dss_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -121,14 +121,14 @@ static struct powerdomain tesla_44xx_pwrdm = {
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 3,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_RET,	/* tesla_edma */
+		[0] = PWRSTS_RET,	/* tesla_edma */
 		[1] = PWRSTS_OFF_RET,	/* tesla_l1 */
 		[2] = PWRSTS_OFF_RET,	/* tesla_l2 */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* tesla_edma */
-		[1] = PWRDM_POWER_ON,	/* tesla_l1 */
-		[2] = PWRDM_POWER_ON,	/* tesla_l2 */
+		[0] = PWRSTS_ON,	/* tesla_edma */
+		[1] = PWRSTS_ON,	/* tesla_l1 */
+		[2] = PWRSTS_ON,	/* tesla_l2 */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -142,10 +142,10 @@ static struct powerdomain wkup_44xx_pwrdm = {
 	.pwrsts		  = PWRSTS_ON,
 	.banks		  = 1,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* wkup_bank */
+		[0] = PWRSTS_OFF,	/* wkup_bank */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* wkup_bank */
+		[0] = PWRSTS_ON,	/* wkup_bank */
 	},
 };
 
@@ -162,7 +162,7 @@ static struct powerdomain cpu0_44xx_pwrdm = {
 		[0] = PWRSTS_OFF_RET,	/* cpu0_l1 */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* cpu0_l1 */
+		[0] = PWRSTS_ON,	/* cpu0_l1 */
 	},
 };
 
@@ -179,7 +179,7 @@ static struct powerdomain cpu1_44xx_pwrdm = {
 		[0] = PWRSTS_OFF_RET,	/* cpu1_l1 */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* cpu1_l1 */
+		[0] = PWRSTS_ON,	/* cpu1_l1 */
 	},
 };
 
@@ -192,10 +192,10 @@ static struct powerdomain emu_44xx_pwrdm = {
 	.pwrsts		  = PWRSTS_OFF_ON,
 	.banks		  = 1,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* emu_bank */
+		[0] = PWRSTS_OFF,	/* emu_bank */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* emu_bank */
+		[0] = PWRSTS_ON,	/* emu_bank */
 	},
 };
 
@@ -211,12 +211,12 @@ static struct powerdomain mpu_44xx_pwrdm = {
 	.pwrsts_mem_ret	= {
 		[0] = PWRSTS_OFF_RET,	/* mpu_l1 */
 		[1] = PWRSTS_OFF_RET,	/* mpu_l2 */
-		[2] = PWRDM_POWER_RET,	/* mpu_ram */
+		[2] = PWRSTS_RET,	/* mpu_ram */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* mpu_l1 */
-		[1] = PWRDM_POWER_ON,	/* mpu_l2 */
-		[2] = PWRDM_POWER_ON,	/* mpu_ram */
+		[0] = PWRSTS_ON,	/* mpu_l1 */
+		[1] = PWRSTS_ON,	/* mpu_l2 */
+		[2] = PWRSTS_ON,	/* mpu_ram */
 	},
 };
 
@@ -227,19 +227,19 @@ static struct powerdomain ivahd_44xx_pwrdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
-	.pwrsts_logic_ret = PWRDM_POWER_OFF,
+	.pwrsts_logic_ret = PWRSTS_OFF,
 	.banks		  = 4,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* hwa_mem */
+		[0] = PWRSTS_OFF,	/* hwa_mem */
 		[1] = PWRSTS_OFF_RET,	/* sl2_mem */
 		[2] = PWRSTS_OFF_RET,	/* tcm1_mem */
 		[3] = PWRSTS_OFF_RET,	/* tcm2_mem */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* hwa_mem */
-		[1] = PWRDM_POWER_ON,	/* sl2_mem */
-		[2] = PWRDM_POWER_ON,	/* tcm1_mem */
-		[3] = PWRDM_POWER_ON,	/* tcm2_mem */
+		[0] = PWRSTS_ON,	/* hwa_mem */
+		[1] = PWRSTS_ON,	/* sl2_mem */
+		[2] = PWRSTS_ON,	/* tcm1_mem */
+		[3] = PWRSTS_ON,	/* tcm2_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -253,10 +253,10 @@ static struct powerdomain cam_44xx_pwrdm = {
 	.pwrsts		  = PWRSTS_OFF_ON,
 	.banks		  = 1,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* cam_mem */
+		[0] = PWRSTS_OFF,	/* cam_mem */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* cam_mem */
+		[0] = PWRSTS_ON,	/* cam_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -271,10 +271,10 @@ static struct powerdomain l3init_44xx_pwrdm = {
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* l3init_bank1 */
+		[0] = PWRSTS_OFF,	/* l3init_bank1 */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* l3init_bank1 */
+		[0] = PWRSTS_ON,	/* l3init_bank1 */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };
@@ -289,12 +289,12 @@ static struct powerdomain l4per_44xx_pwrdm = {
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
 	.banks		  = 2,
 	.pwrsts_mem_ret	= {
-		[0] = PWRDM_POWER_OFF,	/* nonretained_bank */
-		[1] = PWRDM_POWER_RET,	/* retained_bank */
+		[0] = PWRSTS_OFF,	/* nonretained_bank */
+		[1] = PWRSTS_RET,	/* retained_bank */
 	},
 	.pwrsts_mem_on	= {
-		[0] = PWRDM_POWER_ON,	/* nonretained_bank */
-		[1] = PWRDM_POWER_ON,	/* retained_bank */
+		[0] = PWRSTS_ON,	/* nonretained_bank */
+		[1] = PWRSTS_ON,	/* retained_bank */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
 };

+ 2 - 2
arch/arm/mach-omap2/prcm_mpu44xx.h

@@ -38,8 +38,8 @@
 #define OMAP4430_PRCM_MPU_CPU1_INST		0x0800
 
 /* PRCM_MPU clockdomain register offsets (from instance start) */
-#define OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS	0x0018
-#define OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS	0x0018
+#define OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS	0x0018
+#define OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS	0x0018
 
 
 /*

+ 10 - 8
arch/arm/mach-omap2/prm2xxx_3xxx.c

@@ -118,7 +118,8 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
 /**
  * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait
  * @prm_mod: PRM submodule base (e.g. CORE_MOD)
- * @shift: register bit shift corresponding to the reset line to deassert
+ * @rst_shift: register bit shift corresponding to the reset line to deassert
+ * @st_shift: register bit shift for the status of the deasserted submodule
  *
  * Some IPs like dsp or iva contain processors that require an HW
  * reset line to be asserted / deasserted in order to fully enable the
@@ -129,27 +130,28 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
  * -EINVAL upon an argument error, -EEXIST if the submodule was already out
  * of reset, or -EBUSY if the submodule did not exit reset promptly.
  */
-int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift)
+int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
 {
-	u32 mask;
+	u32 rst, st;
 	int c;
 
 	if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
 		return -EINVAL;
 
-	mask = 1 << shift;
+	rst = 1 << rst_shift;
+	st = 1 << st_shift;
 
 	/* Check the current status to avoid de-asserting the line twice */
-	if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, mask) == 0)
+	if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, rst) == 0)
 		return -EEXIST;
 
 	/* Clear the reset status by writing 1 to the status bit */
-	omap2_prm_rmw_mod_reg_bits(0xffffffff, mask, prm_mod, OMAP2_RM_RSTST);
+	omap2_prm_rmw_mod_reg_bits(0xffffffff, st, prm_mod, OMAP2_RM_RSTST);
 	/* de-assert the reset control line */
-	omap2_prm_rmw_mod_reg_bits(mask, 0, prm_mod, OMAP2_RM_RSTCTRL);
+	omap2_prm_rmw_mod_reg_bits(rst, 0, prm_mod, OMAP2_RM_RSTCTRL);
 	/* wait the status to be set */
 	omap_test_timeout(omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
-						  mask),
+						  st),
 			  MAX_MODULE_HARDRESET_WAIT, c);
 
 	return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;

+ 3 - 2
arch/arm/mach-omap2/prm2xxx_3xxx.h

@@ -282,7 +282,8 @@ static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
 		"not suppose to be used on omap4\n");
 	return 0;
 }
-static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift)
+static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
+						u8 st_shift)
 {
 	WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 		"not suppose to be used on omap4\n");
@@ -300,7 +301,7 @@ extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
 /* These omap2_ PRM functions apply to both OMAP2 and 3 */
 extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
 extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
-extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift);
+extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
 
 #endif	/* CONFIG_ARCH_OMAP4 */
 #endif

+ 1 - 1
arch/arm/mach-omap2/smartreflex-class3.c

@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
  */
 
-#include <plat/smartreflex.h>
+#include "smartreflex.h"
 
 static int sr_class3_enable(struct voltagedomain *voltdm)
 {

+ 1 - 1
arch/arm/mach-omap2/smartreflex.c

@@ -26,9 +26,9 @@
 #include <linux/pm_runtime.h>
 
 #include <plat/common.h>
-#include <plat/smartreflex.h>
 
 #include "pm.h"
+#include "smartreflex.h"
 
 #define SMARTREFLEX_NAME_LEN	16
 #define NVALUE_NAME_LEN		40

+ 2 - 1
arch/arm/plat-omap/include/plat/smartreflex.h → arch/arm/mach-omap2/smartreflex.h

@@ -21,7 +21,8 @@
 #define __ASM_ARM_OMAP_SMARTREFLEX_H
 
 #include <linux/platform_device.h>
-#include <plat/voltage.h>
+
+#include "voltage.h"
 
 /*
  * Different Smartreflex IPs version. The v1 is the 65nm version used in

+ 2 - 2
arch/arm/mach-omap2/sr_device.c

@@ -23,9 +23,9 @@
 #include <linux/io.h>
 
 #include <plat/omap_device.h>
-#include <plat/smartreflex.h>
-#include <plat/voltage.h>
 
+#include "smartreflex.h"
+#include "voltage.h"
 #include "control.h"
 #include "pm.h"
 

+ 83 - 0
arch/arm/mach-omap2/vc.h

@@ -0,0 +1,83 @@
+/*
+ * OMAP3/4 Voltage Controller (VC) structure and macro definitions
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_VC_H
+#define __ARCH_ARM_MACH_OMAP2_VC_H
+
+#include <linux/kernel.h>
+
+/**
+ * struct omap_vc_common_data - per-VC register/bitfield data
+ * @cmd_on_mask: ON bitmask in PRM_VC_CMD_VAL* register
+ * @valid: VALID bitmask in PRM_VC_BYPASS_VAL register
+ * @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start
+ * @smps_volra_reg: Offset of PRM_VC_SMPS_VOL_RA reg from PRM start
+ * @bypass_val_reg: Offset of PRM_VC_BYPASS_VAL reg from PRM start
+ * @data_shift: DATA field shift in PRM_VC_BYPASS_VAL register
+ * @slaveaddr_shift: SLAVEADDR field shift in PRM_VC_BYPASS_VAL register
+ * @regaddr_shift: REGADDR field shift in PRM_VC_BYPASS_VAL register
+ * @cmd_on_shift: ON field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_onlp_shift: ONLP field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register
+ *
+ * XXX One of cmd_on_mask and cmd_on_shift are not needed
+ * XXX VALID should probably be a shift, not a mask
+ */
+struct omap_vc_common_data {
+	u32 cmd_on_mask;
+	u32 valid;
+	u8 smps_sa_reg;
+	u8 smps_volra_reg;
+	u8 bypass_val_reg;
+	u8 data_shift;
+	u8 slaveaddr_shift;
+	u8 regaddr_shift;
+	u8 cmd_on_shift;
+	u8 cmd_onlp_shift;
+	u8 cmd_ret_shift;
+	u8 cmd_off_shift;
+};
+
+/**
+ * struct omap_vc_instance_data - VC per-instance data
+ * @vc_common: pointer to VC common data for this platform
+ * @smps_sa_mask: SA* bitmask in the PRM_VC_SMPS_SA register
+ * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
+ * @smps_sa_shift: SA* field shift in the PRM_VC_SMPS_SA register
+ * @smps_volra_shift: VOLRA* field shift in the PRM_VC_VOL_RA register
+ *
+ * XXX It is not necessary to have both a *_mask and a *_shift -
+ *     remove one
+ */
+struct omap_vc_instance_data {
+	const struct omap_vc_common_data *vc_common;
+	u32 smps_sa_mask;
+	u32 smps_volra_mask;
+	u8 cmdval_reg;
+	u8 smps_sa_shift;
+	u8 smps_volra_shift;
+};
+
+extern struct omap_vc_instance_data omap3_vc1_data;
+extern struct omap_vc_instance_data omap3_vc2_data;
+
+extern struct omap_vc_instance_data omap4_vc_mpu_data;
+extern struct omap_vc_instance_data omap4_vc_iva_data;
+extern struct omap_vc_instance_data omap4_vc_core_data;
+
+#endif
+

+ 63 - 0
arch/arm/mach-omap2/vc3xxx_data.c

@@ -0,0 +1,63 @@
+/*
+ * OMAP3 Voltage Controller (VC) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#include "vc.h"
+
+/*
+ * VC data common to 34xx/36xx chips
+ * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
+ */
+static struct omap_vc_common_data omap3_vc_common = {
+	.smps_sa_reg	 = OMAP3_PRM_VC_SMPS_SA_OFFSET,
+	.smps_volra_reg	 = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+	.bypass_val_reg	 = OMAP3_PRM_VC_BYPASS_VAL_OFFSET,
+	.data_shift	 = OMAP3430_DATA_SHIFT,
+	.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT,
+	.regaddr_shift	 = OMAP3430_REGADDR_SHIFT,
+	.valid		 = OMAP3430_VALID_MASK,
+	.cmd_on_shift	 = OMAP3430_VC_CMD_ON_SHIFT,
+	.cmd_on_mask	 = OMAP3430_VC_CMD_ON_MASK,
+	.cmd_onlp_shift	 = OMAP3430_VC_CMD_ONLP_SHIFT,
+	.cmd_ret_shift	 = OMAP3430_VC_CMD_RET_SHIFT,
+	.cmd_off_shift	 = OMAP3430_VC_CMD_OFF_SHIFT,
+};
+
+struct omap_vc_instance_data omap3_vc1_data = {
+	.vc_common = &omap3_vc_common,
+	.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
+	.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
+	.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK,
+	.smps_volra_shift = OMAP3430_VOLRA0_SHIFT,
+	.smps_volra_mask = OMAP3430_VOLRA0_MASK,
+};
+
+struct omap_vc_instance_data omap3_vc2_data = {
+	.vc_common = &omap3_vc_common,
+	.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET,
+	.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
+	.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK,
+	.smps_volra_shift = OMAP3430_VOLRA1_SHIFT,
+	.smps_volra_mask = OMAP3430_VOLRA1_MASK,
+};

+ 75 - 0
arch/arm/mach-omap2/vc44xx_data.c

@@ -0,0 +1,75 @@
+/*
+ * OMAP4 Voltage Controller (VC) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "voltage.h"
+
+#include "vc.h"
+
+/*
+ * VC data common to 44xx chips
+ * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
+ */
+static const struct omap_vc_common_data omap4_vc_common = {
+	.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+	.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+	.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
+	.data_shift = OMAP4430_DATA_SHIFT,
+	.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT,
+	.regaddr_shift = OMAP4430_REGADDR_SHIFT,
+	.valid = OMAP4430_VALID_MASK,
+	.cmd_on_shift = OMAP4430_ON_SHIFT,
+	.cmd_on_mask = OMAP4430_ON_MASK,
+	.cmd_onlp_shift = OMAP4430_ONLP_SHIFT,
+	.cmd_ret_shift = OMAP4430_RET_SHIFT,
+	.cmd_off_shift = OMAP4430_OFF_SHIFT,
+};
+
+/* VC instance data for each controllable voltage line */
+struct omap_vc_instance_data omap4_vc_mpu_data = {
+	.vc_common = &omap4_vc_common,
+	.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
+	.smps_sa_shift = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT,
+	.smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
+	.smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT,
+	.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
+};
+
+struct omap_vc_instance_data omap4_vc_iva_data = {
+	.vc_common = &omap4_vc_common,
+	.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
+	.smps_sa_shift = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT,
+	.smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
+	.smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT,
+	.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
+};
+
+struct omap_vc_instance_data omap4_vc_core_data = {
+	.vc_common = &omap4_vc_common,
+	.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
+	.smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT,
+	.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
+	.smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT,
+	.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
+};
+

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 218 - 552
arch/arm/mach-omap2/voltage.c


+ 59 - 30
arch/arm/plat-omap/include/plat/voltage.h → arch/arm/mach-omap2/voltage.h

@@ -16,6 +16,10 @@
 
 #include <linux/err.h>
 
+#include "vc.h"
+#include "vp.h"
+
+/* XXX document */
 #define VOLTSCALE_VPFORCEUPDATE		1
 #define VOLTSCALE_VCBYPASS		2
 
@@ -27,36 +31,22 @@
 #define OMAP3_VOLTOFFSET	0xff
 #define OMAP3_VOLTSETUP2	0xff
 
-/* Voltage value defines */
-#define OMAP3430_VDD_MPU_OPP1_UV		975000
-#define OMAP3430_VDD_MPU_OPP2_UV		1075000
-#define OMAP3430_VDD_MPU_OPP3_UV		1200000
-#define OMAP3430_VDD_MPU_OPP4_UV		1270000
-#define OMAP3430_VDD_MPU_OPP5_UV		1350000
-
-#define OMAP3430_VDD_CORE_OPP1_UV		975000
-#define OMAP3430_VDD_CORE_OPP2_UV		1050000
-#define OMAP3430_VDD_CORE_OPP3_UV		1150000
-
-#define OMAP3630_VDD_MPU_OPP50_UV		1012500
-#define OMAP3630_VDD_MPU_OPP100_UV		1200000
-#define OMAP3630_VDD_MPU_OPP120_UV		1325000
-#define OMAP3630_VDD_MPU_OPP1G_UV		1375000
-
-#define OMAP3630_VDD_CORE_OPP50_UV		1000000
-#define OMAP3630_VDD_CORE_OPP100_UV		1200000
-
-#define OMAP4430_VDD_MPU_OPP50_UV		930000
-#define OMAP4430_VDD_MPU_OPP100_UV		1100000
-#define OMAP4430_VDD_MPU_OPPTURBO_UV		1260000
-#define OMAP4430_VDD_MPU_OPPNITRO_UV		1350000
-
-#define OMAP4430_VDD_IVA_OPP50_UV		930000
-#define OMAP4430_VDD_IVA_OPP100_UV		1100000
-#define OMAP4430_VDD_IVA_OPPTURBO_UV		1260000
-
-#define OMAP4430_VDD_CORE_OPP50_UV		930000
-#define OMAP4430_VDD_CORE_OPP100_UV		1100000
+/**
+ * struct omap_vfsm_instance_data - per-voltage manager FSM register/bitfield
+ * data
+ * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
+ * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
+ * @voltsetup_shift: SETUP_TIME* field shift in the PRM_VOLTSETUP* register
+ *
+ * XXX What about VOLTOFFSET/VOLTCTRL?
+ * XXX It is not necessary to have both a _mask and a _shift for the same
+ *     bitfield - remove one!
+ */
+struct omap_vfsm_instance_data {
+	u32 voltsetup_mask;
+	u8 voltsetup_reg;
+	u8 voltsetup_shift;
+};
 
 /**
  * struct voltagedomain - omap voltage domain global structure.
@@ -113,6 +103,42 @@ struct omap_volt_pmic_info {
 	u8 (*uv_to_vsel) (unsigned long uV);
 };
 
+/**
+ * omap_vdd_info - Per Voltage Domain info
+ *
+ * @volt_data		: voltage table having the distinct voltages supported
+ *			  by the domain and other associated per voltage data.
+ * @pmic_info		: pmic specific parameters which should be populted by
+ *			  the pmic drivers.
+ * @vp_data		: the register values, shifts, masks for various
+ *			  vp registers
+ * @vp_rt_data          : VP data derived at runtime, not predefined
+ * @vc_data		: structure containing various various vc registers,
+ *			  shifts, masks etc.
+ * @vfsm                : voltage manager FSM data
+ * @voltdm		: pointer to the voltage domain structure
+ * @debug_dir		: debug directory for this voltage domain.
+ * @curr_volt		: current voltage for this vdd.
+ * @vp_enabled		: flag to keep track of whether vp is enabled or not
+ * @volt_scale		: API to scale the voltage of the vdd.
+ */
+struct omap_vdd_info {
+	struct omap_volt_data *volt_data;
+	struct omap_volt_pmic_info *pmic_info;
+	struct omap_vp_instance_data *vp_data;
+	struct omap_vp_runtime_data vp_rt_data;
+	struct omap_vc_instance_data *vc_data;
+	const struct omap_vfsm_instance_data *vfsm;
+	struct voltagedomain voltdm;
+	struct dentry *debug_dir;
+	u32 curr_volt;
+	bool vp_enabled;
+	u32 (*read_reg) (u16 mod, u8 offset);
+	void (*write_reg) (u32 val, u16 mod, u8 offset);
+	int (*volt_scale) (struct omap_vdd_info *vdd,
+		unsigned long target_volt);
+};
+
 unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
 void omap_vp_enable(struct voltagedomain *voltdm);
 void omap_vp_disable(struct voltagedomain *voltdm);
@@ -125,6 +151,9 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
 		unsigned long volt);
 unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
 struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
+int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_mod,
+				   struct omap_vdd_info *omap_vdd_array[],
+				   u8 omap_vdd_count);
 #ifdef CONFIG_PM
 int omap_voltage_register_pmic(struct voltagedomain *voltdm,
 		struct omap_volt_pmic_info *pmic_info);

+ 95 - 0
arch/arm/mach-omap2/voltagedomains3xxx_data.c

@@ -0,0 +1,95 @@
+/*
+ * OMAP3 voltage domain data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+
+#include "prm-regbits-34xx.h"
+#include "omap_opp_data.h"
+#include "voltage.h"
+#include "vc.h"
+#include "vp.h"
+
+/*
+ * VDD data
+ */
+
+static const struct omap_vfsm_instance_data omap3_vdd1_vfsm_data = {
+	.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+	.voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT,
+	.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
+};
+
+static struct omap_vdd_info omap3_vdd1_info = {
+	.vp_data = &omap3_vp1_data,
+	.vc_data = &omap3_vc1_data,
+	.vfsm = &omap3_vdd1_vfsm_data,
+	.voltdm = {
+		.name = "mpu",
+	},
+};
+
+static const struct omap_vfsm_instance_data omap3_vdd2_vfsm_data = {
+	.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+	.voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT,
+	.voltsetup_mask = OMAP3430_SETUP_TIME2_MASK,
+};
+
+static struct omap_vdd_info omap3_vdd2_info = {
+	.vp_data = &omap3_vp2_data,
+	.vc_data = &omap3_vc2_data,
+	.vfsm = &omap3_vdd2_vfsm_data,
+	.voltdm = {
+		.name = "core",
+	},
+};
+
+/* OMAP3 VDD structures */
+static struct omap_vdd_info *omap3_vdd_info[] = {
+	&omap3_vdd1_info,
+	&omap3_vdd2_info,
+};
+
+/* OMAP3 specific voltage init functions */
+static int __init omap3xxx_voltage_early_init(void)
+{
+	s16 prm_mod = OMAP3430_GR_MOD;
+	s16 prm_irqst_ocp_mod = OCP_MOD;
+
+	if (!cpu_is_omap34xx())
+		return 0;
+
+	/*
+	 * XXX Will depend on the process, validation, and binning
+	 * for the currently-running IC
+	 */
+	if (cpu_is_omap3630()) {
+		omap3_vdd1_info.volt_data = omap36xx_vddmpu_volt_data;
+		omap3_vdd2_info.volt_data = omap36xx_vddcore_volt_data;
+	} else {
+		omap3_vdd1_info.volt_data = omap34xx_vddmpu_volt_data;
+		omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data;
+	}
+
+	return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
+				       omap3_vdd_info,
+				       ARRAY_SIZE(omap3_vdd_info));
+};
+core_initcall(omap3xxx_voltage_early_init);

+ 102 - 0
arch/arm/mach-omap2/voltagedomains44xx_data.c

@@ -0,0 +1,102 @@
+/*
+ * OMAP3/OMAP4 Voltage Management Routines
+ *
+ * Author: Thara Gopinath	<thara@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
+#include "voltage.h"
+#include "omap_opp_data.h"
+#include "vc.h"
+#include "vp.h"
+
+static const struct omap_vfsm_instance_data omap4_vdd_mpu_vfsm_data = {
+	.voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_mpu_info = {
+	.vp_data = &omap4_vp_mpu_data,
+	.vc_data = &omap4_vc_mpu_data,
+	.vfsm = &omap4_vdd_mpu_vfsm_data,
+	.voltdm = {
+		.name = "mpu",
+	},
+};
+
+static const struct omap_vfsm_instance_data omap4_vdd_iva_vfsm_data = {
+	.voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_iva_info = {
+	.vp_data = &omap4_vp_iva_data,
+	.vc_data = &omap4_vc_iva_data,
+	.vfsm = &omap4_vdd_iva_vfsm_data,
+	.voltdm = {
+		.name = "iva",
+	},
+};
+
+static const struct omap_vfsm_instance_data omap4_vdd_core_vfsm_data = {
+	.voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_core_info = {
+	.vp_data = &omap4_vp_core_data,
+	.vc_data = &omap4_vc_core_data,
+	.vfsm = &omap4_vdd_core_vfsm_data,
+	.voltdm = {
+		.name = "core",
+	},
+};
+
+/* OMAP4 VDD structures */
+static struct omap_vdd_info *omap4_vdd_info[] = {
+	&omap4_vdd_mpu_info,
+	&omap4_vdd_iva_info,
+	&omap4_vdd_core_info,
+};
+
+/* OMAP4 specific voltage init functions */
+static int __init omap44xx_voltage_early_init(void)
+{
+	s16 prm_mod = OMAP4430_PRM_DEVICE_INST;
+	s16 prm_irqst_ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
+
+	if (!cpu_is_omap44xx())
+		return 0;
+
+	/*
+	 * XXX Will depend on the process, validation, and binning
+	 * for the currently-running IC
+	 */
+	omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
+	omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
+	omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
+
+	return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
+				       omap4_vdd_info,
+				       ARRAY_SIZE(omap4_vdd_info));
+};
+core_initcall(omap44xx_voltage_early_init);

+ 143 - 0
arch/arm/mach-omap2/vp.h

@@ -0,0 +1,143 @@
+/*
+ * OMAP3/4 Voltage Processor (VP) structure and macro definitions
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_VP_H
+#define __ARCH_ARM_MACH_OMAP2_VP_H
+
+#include <linux/kernel.h>
+
+/* XXX document */
+#define VP_IDLE_TIMEOUT		200
+#define VP_TRANXDONE_TIMEOUT	300
+
+
+/**
+ * struct omap_vp_common_data - register data common to all VDDs
+ * @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_timeouten_mask: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_initvdd: INITVDD bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_forceupdate: FORCEUPDATE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_vpenable: VPENABLE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_erroroffset_shift: ERROROFFSET field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_errorgain_shift: ERRORGAIN field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_initvoltage_shift: INITVOLTAGE field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
+ * @vpconfig_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
+ * @vpconfig_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
+ * @vpconfig_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
+ * @vpconfig_vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
+ * @vpconfig_vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
+ * @vpconfig_vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
+ *
+ * XXX It it not necessary to have both a mask and a shift for the same
+ *     bitfield - remove one
+ * XXX Many of these fields are wrongly named -- e.g., vpconfig_smps* -- fix!
+ */
+struct omap_vp_common_data {
+	u32 vpconfig_errorgain_mask;
+	u32 vpconfig_initvoltage_mask;
+	u32 vpconfig_timeouten;
+	u32 vpconfig_initvdd;
+	u32 vpconfig_forceupdate;
+	u32 vpconfig_vpenable;
+	u8 vpconfig_erroroffset_shift;
+	u8 vpconfig_errorgain_shift;
+	u8 vpconfig_initvoltage_shift;
+	u8 vstepmin_stepmin_shift;
+	u8 vstepmin_smpswaittimemin_shift;
+	u8 vstepmax_stepmax_shift;
+	u8 vstepmax_smpswaittimemax_shift;
+	u8 vlimitto_vddmin_shift;
+	u8 vlimitto_vddmax_shift;
+	u8 vlimitto_timeout_shift;
+};
+
+/**
+ * struct omap_vp_prm_irqst_data - PRM_IRQSTATUS_MPU.VP_TRANXDONE_ST data
+ * @prm_irqst_reg: reg offset for PRM_IRQSTATUS_MPU from top of PRM
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ *
+ * XXX prm_irqst_reg does not belong here
+ * XXX Note that on OMAP3, VP_TRANXDONE interrupt may not work due to a
+ *     hardware bug
+ * XXX This structure is probably not needed
+ */
+struct omap_vp_prm_irqst_data {
+	u8 prm_irqst_reg;
+	u32 tranxdone_status;
+};
+
+/**
+ * struct omap_vp_instance_data - VP register offsets (per-VDD)
+ * @vp_common: pointer to struct omap_vp_common_data * for this SoC
+ * @prm_irqst_data: pointer to struct omap_vp_prm_irqst_data for this VDD
+ * @vpconfig: PRM_VP*_CONFIG reg offset from PRM start
+ * @vstepmin: PRM_VP*_VSTEPMIN reg offset from PRM start
+ * @vlimitto: PRM_VP*_VLIMITTO reg offset from PRM start
+ * @vstatus: PRM_VP*_VSTATUS reg offset from PRM start
+ * @voltage: PRM_VP*_VOLTAGE reg offset from PRM start
+ *
+ * XXX vp_common is probably not needed since it is per-SoC
+ */
+struct omap_vp_instance_data {
+	const struct omap_vp_common_data *vp_common;
+	const struct omap_vp_prm_irqst_data *prm_irqst_data;
+	u8 vpconfig;
+	u8 vstepmin;
+	u8 vstepmax;
+	u8 vlimitto;
+	u8 vstatus;
+	u8 voltage;
+};
+
+/**
+ * struct omap_vp_runtime_data - VP data populated at runtime by code
+ * @vpconfig_erroroffset: value of ERROROFFSET bitfield in PRM_VP*_CONFIG
+ * @vpconfig_errorgain: value of ERRORGAIN bitfield in PRM_VP*_CONFIG
+ * @vstepmin_smpswaittimemin: value of SMPSWAITTIMEMIN bitfield in PRM_VP*_VSTEPMIN
+ * @vstepmax_smpswaittimemax: value of SMPSWAITTIMEMAX bitfield in PRM_VP*_VSTEPMAX
+ * @vlimitto_timeout: value of TIMEOUT bitfield in PRM_VP*_VLIMITTO
+ * @vstepmin_stepmin: value of VSTEPMIN bitfield in PRM_VP*_VSTEPMIN
+ * @vstepmax_stepmax: value of VSTEPMAX bitfield in PRM_VP*_VSTEPMAX
+ * @vlimitto_vddmin: value of VDDMIN bitfield in PRM_VP*_VLIMITTO
+ * @vlimitto_vddmax: value of VDDMAX bitfield in PRM_VP*_VLIMITTO
+ *
+ * XXX Is this structure really needed?  Why not just program the
+ * device directly?  They are in PRM space, therefore in the WKUP
+ * powerdomain, so register contents should not be lost in off-mode.
+ * XXX Some of these fields are incorrectly named, e.g., vstep*
+ */
+struct omap_vp_runtime_data {
+	u32 vpconfig_erroroffset;
+	u16 vpconfig_errorgain;
+	u16 vstepmin_smpswaittimemin;
+	u16 vstepmax_smpswaittimemax;
+	u16 vlimitto_timeout;
+	u8 vstepmin_stepmin;
+	u8 vstepmax_stepmax;
+	u8 vlimitto_vddmin;
+	u8 vlimitto_vddmax;
+};
+
+extern struct omap_vp_instance_data omap3_vp1_data;
+extern struct omap_vp_instance_data omap3_vp2_data;
+
+extern struct omap_vp_instance_data omap4_vp_mpu_data;
+extern struct omap_vp_instance_data omap4_vp_iva_data;
+extern struct omap_vp_instance_data omap4_vp_core_data;
+
+#endif

+ 82 - 0
arch/arm/mach-omap2/vp3xxx_data.c

@@ -0,0 +1,82 @@
+/*
+ * OMAP3 Voltage Processor (VP) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+
+/*
+ * VP data common to 34xx/36xx chips
+ * XXX This stuff presumably belongs in the vp3xxx.c or vp.c file.
+ */
+static const struct omap_vp_common_data omap3_vp_common = {
+	.vpconfig_erroroffset_shift = OMAP3430_ERROROFFSET_SHIFT,
+	.vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK,
+	.vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT,
+	.vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT,
+	.vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK,
+	.vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK,
+	.vpconfig_initvdd = OMAP3430_INITVDD_MASK,
+	.vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK,
+	.vpconfig_vpenable = OMAP3430_VPENABLE_MASK,
+	.vstepmin_smpswaittimemin_shift = OMAP3430_SMPSWAITTIMEMIN_SHIFT,
+	.vstepmax_smpswaittimemax_shift = OMAP3430_SMPSWAITTIMEMAX_SHIFT,
+	.vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT,
+	.vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT,
+	.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT,
+	.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT,
+	.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT,
+};
+
+static const struct omap_vp_prm_irqst_data omap3_vp1_prm_irqst_data = {
+	.prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+	.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap3_vp1_data = {
+	.vp_common = &omap3_vp_common,
+	.vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
+	.vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
+	.vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
+	.vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
+	.vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
+	.voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
+	.prm_irqst_data = &omap3_vp1_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap3_vp2_prm_irqst_data = {
+	.prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+	.tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap3_vp2_data = {
+	.vp_common = &omap3_vp_common,
+	.vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
+	.vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
+	.vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
+	.vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
+	.vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
+	.voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
+	.prm_irqst_data = &omap3_vp2_prm_irqst_data,
+};

+ 100 - 0
arch/arm/mach-omap2/vp44xx_data.c

@@ -0,0 +1,100 @@
+/*
+ * OMAP3 Voltage Processor (VP) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+
+/*
+ * VP data common to 44xx chips
+ * XXX This stuff presumably belongs in the vp44xx.c or vp.c file.
+ */
+static const struct omap_vp_common_data omap4_vp_common = {
+	.vpconfig_erroroffset_shift = OMAP4430_ERROROFFSET_SHIFT,
+	.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
+	.vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT,
+	.vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT,
+	.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK,
+	.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK,
+	.vpconfig_initvdd = OMAP4430_INITVDD_MASK,
+	.vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK,
+	.vpconfig_vpenable = OMAP4430_VPENABLE_MASK,
+	.vstepmin_smpswaittimemin_shift = OMAP4430_SMPSWAITTIMEMIN_SHIFT,
+	.vstepmax_smpswaittimemax_shift = OMAP4430_SMPSWAITTIMEMAX_SHIFT,
+	.vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT,
+	.vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT,
+	.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT,
+	.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT,
+	.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_mpu_prm_irqst_data = {
+	.prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
+	.tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_mpu_data = {
+	.vp_common = &omap4_vp_common,
+	.vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
+	.vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
+	.vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
+	.vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
+	.vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
+	.voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
+	.prm_irqst_data = &omap4_vp_mpu_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_iva_prm_irqst_data = {
+	.prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+	.tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_iva_data = {
+	.vp_common = &omap4_vp_common,
+	.vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
+	.vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
+	.vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
+	.vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
+	.vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
+	.voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
+	.prm_irqst_data = &omap4_vp_iva_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_core_prm_irqst_data = {
+	.prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+	.tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_core_data = {
+	.vp_common = &omap4_vp_common,
+	.vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
+	.vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
+	.vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
+	.vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
+	.vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
+	.voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
+	.prm_irqst_data = &omap4_vp_core_prm_irqst_data,
+};
+

+ 71 - 28
arch/arm/plat-omap/clock.c

@@ -37,14 +37,16 @@ static struct clk_functions *arch_clock;
 int clk_enable(struct clk *clk)
 {
 	unsigned long flags;
-	int ret = 0;
+	int ret;
 
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
+	if (!arch_clock || !arch_clock->clk_enable)
+		return -EINVAL;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_enable)
-		ret = arch_clock->clk_enable(clk);
+	ret = arch_clock->clk_enable(clk);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -58,6 +60,9 @@ void clk_disable(struct clk *clk)
 	if (clk == NULL || IS_ERR(clk))
 		return;
 
+	if (!arch_clock || !arch_clock->clk_disable)
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (clk->usecount == 0) {
 		pr_err("Trying disable clock %s with 0 usecount\n",
@@ -66,8 +71,7 @@ void clk_disable(struct clk *clk)
 		goto out;
 	}
 
-	if (arch_clock->clk_disable)
-		arch_clock->clk_disable(clk);
+	arch_clock->clk_disable(clk);
 
 out:
 	spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -77,7 +81,7 @@ EXPORT_SYMBOL(clk_disable);
 unsigned long clk_get_rate(struct clk *clk)
 {
 	unsigned long flags;
-	unsigned long ret = 0;
+	unsigned long ret;
 
 	if (clk == NULL || IS_ERR(clk))
 		return 0;
@@ -97,14 +101,16 @@ EXPORT_SYMBOL(clk_get_rate);
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned long flags;
-	long ret = 0;
+	long ret;
 
 	if (clk == NULL || IS_ERR(clk))
-		return ret;
+		return 0;
+
+	if (!arch_clock || !arch_clock->clk_round_rate)
+		return 0;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_round_rate)
-		ret = arch_clock->clk_round_rate(clk, rate);
+	ret = arch_clock->clk_round_rate(clk, rate);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -119,14 +125,13 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (clk == NULL || IS_ERR(clk))
 		return ret;
 
+	if (!arch_clock || !arch_clock->clk_set_rate)
+		return ret;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_set_rate)
-		ret = arch_clock->clk_set_rate(clk, rate);
-	if (ret == 0) {
-		if (clk->recalc)
-			clk->rate = clk->recalc(clk);
+	ret = arch_clock->clk_set_rate(clk, rate);
+	if (ret == 0)
 		propagate_rate(clk);
-	}
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -141,15 +146,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
 		return ret;
 
+	if (!arch_clock || !arch_clock->clk_set_parent)
+		return ret;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (clk->usecount == 0) {
-		if (arch_clock->clk_set_parent)
-			ret = arch_clock->clk_set_parent(clk, parent);
-		if (ret == 0) {
-			if (clk->recalc)
-				clk->rate = clk->recalc(clk);
+		ret = arch_clock->clk_set_parent(clk, parent);
+		if (ret == 0)
 			propagate_rate(clk);
-		}
 	} else
 		ret = -EBUSY;
 	spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -335,6 +339,38 @@ struct clk *omap_clk_get_by_name(const char *name)
 	return ret;
 }
 
+int omap_clk_enable_autoidle_all(void)
+{
+	struct clk *c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+
+	list_for_each_entry(c, &clocks, node)
+		if (c->ops->allow_idle)
+			c->ops->allow_idle(c);
+
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return 0;
+}
+
+int omap_clk_disable_autoidle_all(void)
+{
+	struct clk *c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+
+	list_for_each_entry(c, &clocks, node)
+		if (c->ops->deny_idle)
+			c->ops->deny_idle(c);
+
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return 0;
+}
+
 /*
  * Low level helpers
  */
@@ -367,9 +403,11 @@ void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
 {
 	unsigned long flags;
 
+	if (!arch_clock || !arch_clock->clk_init_cpufreq_table)
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_init_cpufreq_table)
-		arch_clock->clk_init_cpufreq_table(table);
+	arch_clock->clk_init_cpufreq_table(table);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 }
 
@@ -377,9 +415,11 @@ void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
 {
 	unsigned long flags;
 
+	if (!arch_clock || !arch_clock->clk_exit_cpufreq_table)
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_exit_cpufreq_table)
-		arch_clock->clk_exit_cpufreq_table(table);
+	arch_clock->clk_exit_cpufreq_table(table);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 }
 #endif
@@ -397,6 +437,9 @@ static int __init clk_disable_unused(void)
 	struct clk *ck;
 	unsigned long flags;
 
+	if (!arch_clock || !arch_clock->clk_disable_unused)
+		return 0;
+
 	pr_info("clock: disabling unused clocks to save power\n");
 	list_for_each_entry(ck, &clocks, node) {
 		if (ck->ops == &clkops_null)
@@ -406,14 +449,14 @@ static int __init clk_disable_unused(void)
 			continue;
 
 		spin_lock_irqsave(&clockfw_lock, flags);
-		if (arch_clock->clk_disable_unused)
-			arch_clock->clk_disable_unused(ck);
+		arch_clock->clk_disable_unused(ck);
 		spin_unlock_irqrestore(&clockfw_lock, flags);
 	}
 
 	return 0;
 }
 late_initcall(clk_disable_unused);
+late_initcall(omap_clk_enable_autoidle_all);
 #endif
 
 int __init clk_init(struct clk_functions * custom_clocks)

+ 4 - 0
arch/arm/plat-omap/dmtimer.c

@@ -342,6 +342,10 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
 	l |= 0x02 << 3;  /* Set to smart-idle mode */
 	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
 
+	/* Enable autoidle on OMAP2 / OMAP3 */
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		l |= 0x1 << 0;
+
 	/*
 	 * Enable wake-up on OMAP2 CPUs.
 	 */

+ 20 - 7
arch/arm/plat-omap/include/plat/clock.h

@@ -25,6 +25,8 @@ struct clockdomain;
  * @disable: fn ptr that enables the current clock in hardware
  * @find_idlest: function returning the IDLEST register for the clock's IP blk
  * @find_companion: function returning the "companion" clk reg for the clock
+ * @allow_idle: fn ptr that enables autoidle for the current clock in hardware
+ * @deny_idle: fn ptr that disables autoidle for the current clock in hardware
  *
  * A "companion" clk is an accompanying clock to the one being queried
  * that must be enabled for the IP module connected to the clock to
@@ -42,6 +44,8 @@ struct clkops {
 					       u8 *, u8 *);
 	void			(*find_companion)(struct clk *, void __iomem **,
 						  u8 *);
+	void			(*allow_idle)(struct clk *);
+	void			(*deny_idle)(struct clk *);
 };
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
@@ -105,7 +109,6 @@ struct clksel {
  * @clk_ref: struct clk pointer to the clock's reference clock input
  * @control_reg: register containing the DPLL mode bitfield
  * @enable_mask: mask of the DPLL mode bitfield in @control_reg
- * @rate_tolerance: maximum variance allowed from target rate (in Hz)
  * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
  * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
  * @max_multiplier: maximum valid non-bypass multiplier value (actual)
@@ -131,12 +134,9 @@ struct clksel {
  * XXX Some DPLLs have multiple bypass inputs, so it's not technically
  * correct to only have one @clk_bypass pointer.
  *
- * XXX @rate_tolerance should probably be deprecated - currently there
- * don't seem to be any usecases for DPLL rounding that is not exact.
- *
  * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
  * @last_rounded_n) should be separated from the runtime-fixed fields
- * and placed into a differenct structure, so that the runtime-fixed data
+ * and placed into a different structure, so that the runtime-fixed data
  * can be placed into read-only space.
  */
 struct dpll_data {
@@ -147,7 +147,6 @@ struct dpll_data {
 	struct clk		*clk_ref;
 	void __iomem		*control_reg;
 	u32			enable_mask;
-	unsigned int		rate_tolerance;
 	unsigned long		last_rounded_rate;
 	u16			last_rounded_m;
 	u16			max_multiplier;
@@ -172,12 +171,24 @@ struct dpll_data {
 
 #endif
 
-/* struct clk.flags possibilities */
+/*
+ * struct clk.flags possibilities
+ *
+ * XXX document the rest of the clock flags here
+ *
+ * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL
+ *     bits share the same register.  This flag allows the
+ *     omap4_dpllmx*() code to determine which GATE_CTRL bit field
+ *     should be used.  This is a temporary solution - a better approach
+ *     would be to associate clock type-specific data with the clock,
+ *     similar to the struct dpll_data approach.
+ */
 #define ENABLE_REG_32BIT	(1 << 0)	/* Use 32-bit access */
 #define CLOCK_IDLE_CONTROL	(1 << 1)
 #define CLOCK_NO_IDLE_PARENT	(1 << 2)
 #define ENABLE_ON_INIT		(1 << 3)	/* Enable upon framework init */
 #define INVERT_ENABLE		(1 << 4)	/* 0 enables, 1 disables */
+#define CLOCK_CLKOUTX2		(1 << 5)
 
 /**
  * struct clk - OMAP struct clk
@@ -293,6 +304,8 @@ extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
 extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
 #endif
 extern struct clk *omap_clk_get_by_name(const char *name);
+extern int omap_clk_enable_autoidle_all(void);
+extern int omap_clk_disable_autoidle_all(void);
 
 extern const struct clkops clkops_null;
 

+ 6 - 2
arch/arm/plat-omap/include/plat/omap_hwmod.h

@@ -35,7 +35,6 @@
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
 #include <plat/cpu.h>
-#include <plat/voltage.h>
 
 struct omap_device;
 
@@ -125,6 +124,7 @@ struct omap_hwmod_dma_info {
  * struct omap_hwmod_rst_info - IPs reset lines use by hwmod
  * @name: name of the reset line (module local name)
  * @rst_shift: Offset of the reset bit
+ * @st_shift: Offset of the reset status bit (OMAP2/3 only)
  *
  * @name should be something short, e.g., "cpu0" or "rst". It is defined
  * locally to the hwmod.
@@ -132,6 +132,7 @@ struct omap_hwmod_dma_info {
 struct omap_hwmod_rst_info {
 	const char	*name;
 	u8		rst_shift;
+	u8		st_shift;
 };
 
 /**
@@ -377,7 +378,7 @@ struct omap_hwmod_omap4_prcm {
  * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
  *     controller, etc. XXX probably belongs outside the main hwmod file
  *     XXX Should be HWMOD_SETUP_NO_IDLE
- * HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
+ * HWMOD_NO_OCP_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
  *     when module is enabled, rather than the default, which is to
  *     enable autoidle
  * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
@@ -561,6 +562,7 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
 int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
 
 int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
+int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle);
 
 int omap_hwmod_reset(struct omap_hwmod *oh);
 void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
@@ -595,6 +597,8 @@ int omap_hwmod_for_each_by_class(const char *classname,
 int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
 u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 
+int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
+
 /*
  * Chip variant-specific hwmod init routines - XXX should be converted
  * to use initcalls once the initial boot ordering is straightened out

+ 26 - 10
arch/arm/plat-omap/omap_device.c

@@ -83,9 +83,11 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clkdev.h>
 
 #include <plat/omap_device.h>
 #include <plat/omap_hwmod.h>
+#include <plat/clock.h>
 
 /* These parameters are passed to _omap_device_{de,}activate() */
 #define USE_WAKEUP_LAT			0
@@ -239,12 +241,12 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
 }
 
 /**
- * _add_optional_clock_alias - Add clock alias for hwmod optional clocks
+ * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks
  * @od: struct omap_device *od
  *
  * For every optional clock present per hwmod per omap_device, this function
- * adds an entry in the clocks list of the form <dev-id=dev_name, con-id=role>
- * if an entry is already present in it with the form <dev-id=NULL, con-id=role>
+ * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role>
+ * if it does not exist already.
  *
  * The function is called from inside omap_device_build_ss(), after
  * omap_device_register.
@@ -254,25 +256,39 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
  *
  * No return value.
  */
-static void _add_optional_clock_alias(struct omap_device *od,
+static void _add_optional_clock_clkdev(struct omap_device *od,
 				      struct omap_hwmod *oh)
 {
 	int i;
 
 	for (i = 0; i < oh->opt_clks_cnt; i++) {
 		struct omap_hwmod_opt_clk *oc;
-		int r;
+		struct clk *r;
+		struct clk_lookup *l;
 
 		oc = &oh->opt_clks[i];
 
 		if (!oc->_clk)
 			continue;
 
-		r = clk_add_alias(oc->role, dev_name(&od->pdev.dev),
-				  (char *)oc->clk, &od->pdev.dev);
-		if (r)
-			pr_err("omap_device: %s: clk_add_alias for %s failed\n",
+		r = clk_get_sys(dev_name(&od->pdev.dev), oc->role);
+		if (!IS_ERR(r))
+			continue; /* clkdev entry exists */
+
+		r = omap_clk_get_by_name((char *)oc->clk);
+		if (IS_ERR(r)) {
+			pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
+			       dev_name(&od->pdev.dev), oc->clk);
+			continue;
+		}
+
+		l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev));
+		if (!l) {
+			pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
 			       dev_name(&od->pdev.dev), oc->role);
+			return;
+		}
+		clkdev_add(l);
 	}
 }
 
@@ -480,7 +496,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
 
 	for (i = 0; i < oh_cnt; i++) {
 		hwmods[i]->od = od;
-		_add_optional_clock_alias(od, hwmods[i]);
+		_add_optional_clock_clkdev(od, hwmods[i]);
 	}
 
 	if (ret)

+ 3 - 3
drivers/mmc/host/omap_hsmmc.c

@@ -2117,14 +2117,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
 	/* we start off in DISABLED state */
 	host->dpm_state = DISABLED;
 
-	if (mmc_host_enable(host->mmc) != 0) {
+	if (clk_enable(host->iclk) != 0) {
 		clk_put(host->iclk);
 		clk_put(host->fclk);
 		goto err1;
 	}
 
-	if (clk_enable(host->iclk) != 0) {
-		mmc_host_disable(host->mmc);
+	if (mmc_host_enable(host->mmc) != 0) {
+		clk_disable(host->iclk);
 		clk_put(host->iclk);
 		clk_put(host->fclk);
 		goto err1;

+ 23 - 2
drivers/watchdog/omap_wdt.c

@@ -124,6 +124,8 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
 	u32 pre_margin = GET_WLDR_VAL(timer_margin);
 	void __iomem *base = wdev->base;
 
+	pm_runtime_get_sync(wdev->dev);
+
 	/* just count up at 32 KHz */
 	while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
 		cpu_relax();
@@ -131,6 +133,8 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
 	__raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR);
 	while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
 		cpu_relax();
+
+	pm_runtime_put_sync(wdev->dev);
 }
 
 /*
@@ -160,6 +164,8 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
 	omap_wdt_ping(wdev); /* trigger loading of new timeout value */
 	omap_wdt_enable(wdev);
 
+	pm_runtime_put_sync(wdev->dev);
+
 	return nonseekable_open(inode, file);
 }
 
@@ -171,6 +177,7 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
 	 *      Shut off the timer unless NOWAYOUT is defined.
 	 */
 #ifndef CONFIG_WATCHDOG_NOWAYOUT
+	pm_runtime_get_sync(wdev->dev);
 
 	omap_wdt_disable(wdev);
 
@@ -190,9 +197,11 @@ static ssize_t omap_wdt_write(struct file *file, const char __user *data,
 
 	/* Refresh LOAD_TIME. */
 	if (len) {
+		pm_runtime_get_sync(wdev->dev);
 		spin_lock(&wdt_lock);
 		omap_wdt_ping(wdev);
 		spin_unlock(&wdt_lock);
+		pm_runtime_put_sync(wdev->dev);
 	}
 	return len;
 }
@@ -224,15 +233,18 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
 			return put_user(omap_prcm_get_reset_sources(),
 					(int __user *)arg);
 	case WDIOC_KEEPALIVE:
+		pm_runtime_get_sync(wdev->dev);
 		spin_lock(&wdt_lock);
 		omap_wdt_ping(wdev);
 		spin_unlock(&wdt_lock);
+		pm_runtime_put_sync(wdev->dev);
 		return 0;
 	case WDIOC_SETTIMEOUT:
 		if (get_user(new_margin, (int __user *)arg))
 			return -EFAULT;
 		omap_wdt_adjust_timeout(new_margin);
 
+		pm_runtime_get_sync(wdev->dev);
 		spin_lock(&wdt_lock);
 		omap_wdt_disable(wdev);
 		omap_wdt_set_timeout(wdev);
@@ -240,6 +252,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
 
 		omap_wdt_ping(wdev);
 		spin_unlock(&wdt_lock);
+		pm_runtime_put_sync(wdev->dev);
 		/* Fall */
 	case WDIOC_GETTIMEOUT:
 		return put_user(timer_margin, (int __user *)arg);
@@ -345,8 +358,11 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
 {
 	struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
 
-	if (wdev->omap_wdt_users)
+	if (wdev->omap_wdt_users) {
+		pm_runtime_get_sync(wdev->dev);
 		omap_wdt_disable(wdev);
+		pm_runtime_put_sync(wdev->dev);
+	}
 }
 
 static int __devexit omap_wdt_remove(struct platform_device *pdev)
@@ -381,8 +397,11 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
 
-	if (wdev->omap_wdt_users)
+	if (wdev->omap_wdt_users) {
+		pm_runtime_get_sync(wdev->dev);
 		omap_wdt_disable(wdev);
+		pm_runtime_put_sync(wdev->dev);
+	}
 
 	return 0;
 }
@@ -392,8 +411,10 @@ static int omap_wdt_resume(struct platform_device *pdev)
 	struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
 
 	if (wdev->omap_wdt_users) {
+		pm_runtime_get_sync(wdev->dev);
 		omap_wdt_enable(wdev);
 		omap_wdt_ping(wdev);
+		pm_runtime_put_sync(wdev->dev);
 	}
 
 	return 0;

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است