瀏覽代碼

Merge tag 'omap-for-v4.8/soc-pt2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/soc

Merge "Few more omap SoC changes for v4.8 merge window" from Tony Lindgren:

- Fix a make randconfig build error for recent SMP kexec changes

- A series of clock related fixes to prepare things for moving
  device clkctrl register handling to drivers/clk

* tag 'omap-for-v4.8/soc-pt2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: AM33xx: fix module_wait_ready without clkctrl register
  ARM: OMAP2+: clockdomain: add usecounting support to autoidle APIs
  ARM: OMAP2+: timer: change order of hwmod data handling
  ARM: OMAP2+: hwmod: fetch main_clk based on hwmod name
  ARM: OMAP2+: omap_device: create clock alias purely from DT data
  ARM: OMAP2+: Fix build with CONFIG_SMP and CONFIG_PM is not set
Arnd Bergmann 9 年之前
父節點
當前提交
04b6d0a300

+ 4 - 1
arch/arm/mach-omap2/Makefile

@@ -78,13 +78,16 @@ obj-$(CONFIG_ARCH_OMAP4)		+= opp4xxx_data.o
 endif
 endif
 
 
 # Power Management
 # Power Management
+omap-4-5-pm-common			= omap-mpuss-lowpower.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-pm-common)
+obj-$(CONFIG_ARCH_OMAP5)		+= $(omap-4-5-pm-common)
 obj-$(CONFIG_OMAP_PM_NOOP)		+= omap-pm-noop.o
 obj-$(CONFIG_OMAP_PM_NOOP)		+= omap-pm-noop.o
 
 
 ifeq ($(CONFIG_PM),y)
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
-omap-4-5-pm-common			=  pm44xx.o omap-mpuss-lowpower.o
+omap-4-5-pm-common			+= pm44xx.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-pm-common)
 obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-pm-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-pm-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-pm-common)
 obj-$(CONFIG_SOC_DRA7XX)		+= $(omap-4-5-pm-common)
 obj-$(CONFIG_SOC_DRA7XX)		+= $(omap-4-5-pm-common)

+ 24 - 12
arch/arm/mach-omap2/clockdomain.c

@@ -465,10 +465,7 @@ int clkdm_complete_init(void)
 		return -EACCES;
 		return -EACCES;
 
 
 	list_for_each_entry(clkdm, &clkdm_list, node) {
 	list_for_each_entry(clkdm, &clkdm_list, node) {
-		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-			clkdm_wakeup(clkdm);
-		else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
-			clkdm_deny_idle(clkdm);
+		clkdm_deny_idle(clkdm);
 
 
 		_resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs);
 		_resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs);
 		clkdm_clear_all_wkdeps(clkdm);
 		clkdm_clear_all_wkdeps(clkdm);
@@ -925,11 +922,20 @@ void clkdm_allow_idle_nolock(struct clockdomain *clkdm)
 	if (!clkdm)
 	if (!clkdm)
 		return;
 		return;
 
 
-	if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
-		pr_debug("clock: %s: automatic idle transitions cannot be enabled\n",
-			 clkdm->name);
+	if (!WARN_ON(!clkdm->forcewake_count))
+		clkdm->forcewake_count--;
+
+	if (clkdm->forcewake_count)
+		return;
+
+	if (!clkdm->usecount && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
+		clkdm_sleep_nolock(clkdm);
+
+	if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO))
+		return;
+
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)
 		return;
 		return;
-	}
 
 
 	if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle)
 	if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle)
 		return;
 		return;
@@ -974,11 +980,17 @@ void clkdm_deny_idle_nolock(struct clockdomain *clkdm)
 	if (!clkdm)
 	if (!clkdm)
 		return;
 		return;
 
 
-	if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) {
-		pr_debug("clockdomain: %s: automatic idle transitions cannot be disabled\n",
-			 clkdm->name);
+	if (clkdm->forcewake_count++)
+		return;
+
+	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+		clkdm_wakeup_nolock(clkdm);
+
+	if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO))
+		return;
+
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)
 		return;
 		return;
-	}
 
 
 	if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle)
 	if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle)
 		return;
 		return;

+ 2 - 0
arch/arm/mach-omap2/clockdomain.h

@@ -114,6 +114,7 @@ struct omap_hwmod;
  * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
  * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
  * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
  * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
  * @usecount: Usecount tracking
  * @usecount: Usecount tracking
+ * @forcewake_count: Usecount for forcing the domain active
  * @node: list_head to link all clockdomains together
  * @node: list_head to link all clockdomains together
  *
  *
  * @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only)
  * @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only)
@@ -138,6 +139,7 @@ struct clockdomain {
 	struct clkdm_dep *wkdep_srcs;
 	struct clkdm_dep *wkdep_srcs;
 	struct clkdm_dep *sleepdep_srcs;
 	struct clkdm_dep *sleepdep_srcs;
 	int usecount;
 	int usecount;
+	int forcewake_count;
 	struct list_head node;
 	struct list_head node;
 };
 };
 
 

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

@@ -220,6 +220,9 @@ static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs,
 {
 {
 	int i = 0;
 	int i = 0;
 
 
+	if (!clkctrl_offs)
+		return 0;
+
 	omap_test_timeout(_is_module_ready(inst, clkctrl_offs),
 	omap_test_timeout(_is_module_ready(inst, clkctrl_offs),
 			  MAX_MODULE_READY_TIME, i);
 			  MAX_MODULE_READY_TIME, i);
 
 

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

@@ -140,7 +140,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 		    mpuss_can_lose_context)
 		    mpuss_can_lose_context)
 			gic_dist_disable();
 			gic_dist_disable();
 
 
-		clkdm_wakeup(cpu_clkdm[1]);
+		clkdm_deny_idle(cpu_clkdm[1]);
 		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
 		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
 		clkdm_allow_idle(cpu_clkdm[1]);
 		clkdm_allow_idle(cpu_clkdm[1]);
 
 

+ 1 - 1
arch/arm/mach-omap2/omap-mpuss-lowpower.c

@@ -64,7 +64,7 @@
 
 
 static void __iomem *sar_base;
 static void __iomem *sar_base;
 
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_PM) && defined(CONFIG_SMP)
 
 
 struct omap4_cpu_pm_info {
 struct omap4_cpu_pm_info {
 	struct powerdomain *pwrdm;
 	struct powerdomain *pwrdm;

+ 1 - 1
arch/arm/mach-omap2/omap-smp.c

@@ -200,7 +200,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
 		 * Ensure that CPU power state is set to ON to avoid CPU
 		 * Ensure that CPU power state is set to ON to avoid CPU
 		 * powerdomain transition on wfi
 		 * powerdomain transition on wfi
 		 */
 		 */
-		clkdm_wakeup_nolock(cpu1_clkdm);
+		clkdm_deny_idle_nolock(cpu1_clkdm);
 		pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
 		pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
 		clkdm_allow_idle_nolock(cpu1_clkdm);
 		clkdm_allow_idle_nolock(cpu1_clkdm);
 
 

+ 16 - 1
arch/arm/mach-omap2/omap_device.c

@@ -63,7 +63,22 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias,
 		return;
 		return;
 	}
 	}
 
 
-	rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev), clk_name, NULL);
+	r = clk_get_sys(NULL, clk_name);
+
+	if (IS_ERR(r) && of_have_populated_dt()) {
+		struct of_phandle_args clkspec;
+
+		clkspec.np = of_find_node_by_name(NULL, clk_name);
+
+		r = of_clk_get_from_provider(&clkspec);
+
+		rc = clk_register_clkdev(r, clk_alias,
+					 dev_name(&od->pdev->dev));
+	} else {
+		rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev),
+				   clk_name, NULL);
+	}
+
 	if (rc) {
 	if (rc) {
 		if (rc == -ENODEV || rc == -ENOMEM)
 		if (rc == -ENODEV || rc == -ENOMEM)
 			dev_err(&od->pdev->dev,
 			dev_err(&od->pdev->dev,

+ 62 - 20
arch/arm/mach-omap2/omap_hwmod.c

@@ -178,6 +178,11 @@
  */
  */
 #define OMAP4_RST_CTRL_ST_OFFSET	4
 #define OMAP4_RST_CTRL_ST_OFFSET	4
 
 
+/*
+ * Maximum length for module clock handle names
+ */
+#define MOD_CLK_MAX_NAME_LEN		32
+
 /**
 /**
  * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
  * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
  * @enable_module: function to enable a module (via MODULEMODE)
  * @enable_module: function to enable a module (via MODULEMODE)
@@ -200,6 +205,7 @@ struct omap_hwmod_soc_ops {
 	int (*init_clkdm)(struct omap_hwmod *oh);
 	int (*init_clkdm)(struct omap_hwmod *oh);
 	void (*update_context_lost)(struct omap_hwmod *oh);
 	void (*update_context_lost)(struct omap_hwmod *oh);
 	int (*get_context_lost)(struct omap_hwmod *oh);
 	int (*get_context_lost)(struct omap_hwmod *oh);
+	int (*disable_direct_prcm)(struct omap_hwmod *oh);
 };
 };
 
 
 /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
 /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -776,17 +782,35 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
  * @oh: struct omap_hwmod *
  * @oh: struct omap_hwmod *
  *
  *
  * Called from _init_clocks().  Populates the @oh _clk (main
  * Called from _init_clocks().  Populates the @oh _clk (main
- * functional clock pointer) if a main_clk is present.  Returns 0 on
- * success or -EINVAL on error.
+ * functional clock pointer) if a clock matching the hwmod name is found,
+ * or a main_clk is present.  Returns 0 on success or -EINVAL on error.
  */
  */
 static int _init_main_clk(struct omap_hwmod *oh)
 static int _init_main_clk(struct omap_hwmod *oh)
 {
 {
 	int ret = 0;
 	int ret = 0;
+	char name[MOD_CLK_MAX_NAME_LEN];
+	struct clk *clk;
 
 
-	if (!oh->main_clk)
-		return 0;
+	/* +7 magic comes from '_mod_ck' suffix */
+	if (strlen(oh->name) + 7 > MOD_CLK_MAX_NAME_LEN)
+		pr_warn("%s: warning: cropping name for %s\n", __func__,
+			oh->name);
+
+	strncpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - 7);
+	strcat(name, "_mod_ck");
+
+	clk = clk_get(NULL, name);
+	if (!IS_ERR(clk)) {
+		oh->_clk = clk;
+		soc_ops.disable_direct_prcm(oh);
+		oh->main_clk = kstrdup(name, GFP_KERNEL);
+	} else {
+		if (!oh->main_clk)
+			return 0;
+
+		oh->_clk = clk_get(NULL, oh->main_clk);
+	}
 
 
-	oh->_clk = clk_get(NULL, oh->main_clk);
 	if (IS_ERR(oh->_clk)) {
 	if (IS_ERR(oh->_clk)) {
 		pr_warn("omap_hwmod: %s: cannot clk_get main_clk %s\n",
 		pr_warn("omap_hwmod: %s: cannot clk_get main_clk %s\n",
 			oh->name, oh->main_clk);
 			oh->name, oh->main_clk);
@@ -1678,7 +1702,6 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
 {
 {
 	struct omap_hwmod_rst_info ohri;
 	struct omap_hwmod_rst_info ohri;
 	int ret = -EINVAL;
 	int ret = -EINVAL;
-	int hwsup = 0;
 
 
 	if (!oh)
 	if (!oh)
 		return -EINVAL;
 		return -EINVAL;
@@ -1696,7 +1719,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
 		 * might not be completed. The clockdomain can be set
 		 * might not be completed. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 * in HW_AUTO only when the module become ready.
 		 */
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm);
+		clkdm_deny_idle(oh->clkdm);
 		ret = clkdm_hwmod_enable(oh->clkdm, oh);
 		ret = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (ret) {
 		if (ret) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
@@ -1723,8 +1746,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
 		 * Set the clockdomain to HW_AUTO, assuming that the
 		 * Set the clockdomain to HW_AUTO, assuming that the
 		 * previous state was HW_AUTO.
 		 * previous state was HW_AUTO.
 		 */
 		 */
-		if (hwsup)
-			clkdm_allow_idle(oh->clkdm);
+		clkdm_allow_idle(oh->clkdm);
 
 
 		clkdm_hwmod_disable(oh->clkdm, oh);
 		clkdm_hwmod_disable(oh->clkdm, oh);
 	}
 	}
@@ -2078,7 +2100,6 @@ static int _enable_preprogram(struct omap_hwmod *oh)
 static int _enable(struct omap_hwmod *oh)
 static int _enable(struct omap_hwmod *oh)
 {
 {
 	int r;
 	int r;
-	int hwsup = 0;
 
 
 	pr_debug("omap_hwmod: %s: enabling\n", oh->name);
 	pr_debug("omap_hwmod: %s: enabling\n", oh->name);
 
 
@@ -2138,8 +2159,7 @@ static int _enable(struct omap_hwmod *oh)
 		 * completely the module. The clockdomain can be set
 		 * completely the module. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 * in HW_AUTO only when the module become ready.
 		 */
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm) &&
-			!clkdm_missing_idle_reporting(oh->clkdm);
+		clkdm_deny_idle(oh->clkdm);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (r) {
 		if (r) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
@@ -2159,14 +2179,10 @@ static int _enable(struct omap_hwmod *oh)
 
 
 	r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
 	r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
 		-EINVAL;
 		-EINVAL;
-	if (!r) {
-		/*
-		 * Set the clockdomain to HW_AUTO only if the target is ready,
-		 * assuming that the previous state was HW_AUTO
-		 */
-		if (oh->clkdm && hwsup)
-			clkdm_allow_idle(oh->clkdm);
+	if (oh->clkdm)
+		clkdm_allow_idle(oh->clkdm);
 
 
+	if (!r) {
 		oh->_state = _HWMOD_STATE_ENABLED;
 		oh->_state = _HWMOD_STATE_ENABLED;
 
 
 		/* Access the sysconfig only if the target is ready */
 		/* Access the sysconfig only if the target is ready */
@@ -2220,6 +2236,9 @@ static int _idle(struct omap_hwmod *oh)
 		_idle_sysc(oh);
 		_idle_sysc(oh);
 	_del_initiator_dep(oh, mpu_oh);
 	_del_initiator_dep(oh, mpu_oh);
 
 
+	if (oh->clkdm)
+		clkdm_deny_idle(oh->clkdm);
+
 	if (oh->flags & HWMOD_BLOCK_WFI)
 	if (oh->flags & HWMOD_BLOCK_WFI)
 		cpu_idle_poll_ctrl(false);
 		cpu_idle_poll_ctrl(false);
 	if (soc_ops.disable_module)
 	if (soc_ops.disable_module)
@@ -2232,8 +2251,10 @@ static int _idle(struct omap_hwmod *oh)
 	 * transition to complete properly.
 	 * transition to complete properly.
 	 */
 	 */
 	_disable_clocks(oh);
 	_disable_clocks(oh);
-	if (oh->clkdm)
+	if (oh->clkdm) {
+		clkdm_allow_idle(oh->clkdm);
 		clkdm_hwmod_disable(oh->clkdm, oh);
 		clkdm_hwmod_disable(oh->clkdm, oh);
+	}
 
 
 	/* Mux pins for device idle if populated */
 	/* Mux pins for device idle if populated */
 	if (oh->mux && oh->mux->pads_dynamic) {
 	if (oh->mux && oh->mux->pads_dynamic) {
@@ -3090,6 +3111,25 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
 					      oh->prcm.omap4.rstctrl_offs);
 					      oh->prcm.omap4.rstctrl_offs);
 }
 }
 
 
+/**
+ * _omap4_disable_direct_prcm - disable direct PRCM control for hwmod
+ * @oh: struct omap_hwmod * to disable control for
+ *
+ * Disables direct PRCM clkctrl done by hwmod core. Instead, the hwmod
+ * will be using its main_clk to enable/disable the module. Returns
+ * 0 if successful.
+ */
+static int _omap4_disable_direct_prcm(struct omap_hwmod *oh)
+{
+	if (!oh)
+		return -EINVAL;
+
+	oh->prcm.omap4.clkctrl_offs = 0;
+	oh->prcm.omap4.modulemode = 0;
+
+	return 0;
+}
+
 /**
 /**
  * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
  * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
  * @oh: struct omap_hwmod * to deassert hardreset
  * @oh: struct omap_hwmod * to deassert hardreset
@@ -3913,6 +3953,7 @@ void __init omap_hwmod_init(void)
 		soc_ops.init_clkdm = _init_clkdm;
 		soc_ops.init_clkdm = _init_clkdm;
 		soc_ops.update_context_lost = _omap4_update_context_lost;
 		soc_ops.update_context_lost = _omap4_update_context_lost;
 		soc_ops.get_context_lost = _omap4_get_context_lost;
 		soc_ops.get_context_lost = _omap4_get_context_lost;
+		soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
 	} else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
 	} else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
 		   soc_is_am43xx()) {
 		   soc_is_am43xx()) {
 		soc_ops.enable_module = _omap4_enable_module;
 		soc_ops.enable_module = _omap4_enable_module;
@@ -3922,6 +3963,7 @@ void __init omap_hwmod_init(void)
 		soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
 		soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
 		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
 		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
 		soc_ops.init_clkdm = _init_clkdm;
 		soc_ops.init_clkdm = _init_clkdm;
+		soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
 	} else {
 	} else {
 		WARN(1, "omap_hwmod: unknown SoC type\n");
 		WARN(1, "omap_hwmod: unknown SoC type\n");
 	}
 	}

+ 1 - 7
arch/arm/mach-omap2/pm.c

@@ -110,13 +110,7 @@ static void __init omap2_init_processor_devices(void)
 
 
 int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
 int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
 {
-	/* XXX The usecount test is racy */
-	if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
-	    !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
-		clkdm_allow_idle(clkdm);
-	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
-		 clkdm->usecount == 0)
-		clkdm_sleep(clkdm);
+	clkdm_allow_idle(clkdm);
 	return 0;
 	return 0;
 }
 }
 
 

+ 6 - 14
arch/arm/mach-omap2/powerdomain.c

@@ -222,7 +222,6 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
  * @pwrdm: struct powerdomain * to operate on
  * @pwrdm: struct powerdomain * to operate on
  * @curr_pwrst: current power state of @pwrdm
  * @curr_pwrst: current power state of @pwrdm
  * @pwrst: power state to switch to
  * @pwrst: power state to switch to
- * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised
  *
  *
  * Determine whether the powerdomain needs to be turned on before
  * Determine whether the powerdomain needs to be turned on before
  * attempting to switch power states.  Called by
  * attempting to switch power states.  Called by
@@ -233,8 +232,7 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
  * "Types of sleep_switch" comment above).
  * "Types of sleep_switch" comment above).
  */
  */
 static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
 static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
-					       u8 curr_pwrst, u8 pwrst,
-					       bool *hwsup)
+					       u8 curr_pwrst, u8 pwrst)
 {
 {
 	u8 sleep_switch;
 	u8 sleep_switch;
 
 
@@ -244,8 +242,7 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
 		    arch_pwrdm->pwrdm_set_lowpwrstchange) {
 		    arch_pwrdm->pwrdm_set_lowpwrstchange) {
 			sleep_switch = LOWPOWERSTATE_SWITCH;
 			sleep_switch = LOWPOWERSTATE_SWITCH;
 		} else {
 		} else {
-			*hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
-			clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]);
+			clkdm_deny_idle_nolock(pwrdm->pwrdm_clkdms[0]);
 			sleep_switch = FORCEWAKEUP_SWITCH;
 			sleep_switch = FORCEWAKEUP_SWITCH;
 		}
 		}
 	} else {
 	} else {
@@ -259,7 +256,6 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
  * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
  * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
  * @pwrdm: struct powerdomain * to operate on
  * @pwrdm: struct powerdomain * to operate on
  * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
  * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
- * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode?
  *
  *
  * Restore the clockdomain state perturbed by
  * Restore the clockdomain state perturbed by
  * _pwrdm_save_clkdm_state_and_activate(), and call the power state
  * _pwrdm_save_clkdm_state_and_activate(), and call the power state
@@ -270,14 +266,11 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
  * software-supervised sleep.  No return value.
  * software-supervised sleep.  No return value.
  */
  */
 static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
 static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
-				       u8 sleep_switch, bool hwsup)
+				       u8 sleep_switch)
 {
 {
 	switch (sleep_switch) {
 	switch (sleep_switch) {
 	case FORCEWAKEUP_SWITCH:
 	case FORCEWAKEUP_SWITCH:
-		if (hwsup)
-			clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
-		else
-			clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]);
+		clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
 		break;
 		break;
 	case LOWPOWERSTATE_SWITCH:
 	case LOWPOWERSTATE_SWITCH:
 		if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
 		if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
@@ -1092,7 +1085,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
 	u8 next_pwrst, sleep_switch;
 	u8 next_pwrst, sleep_switch;
 	int curr_pwrst;
 	int curr_pwrst;
 	int ret = 0;
 	int ret = 0;
-	bool hwsup = false;
 
 
 	if (!pwrdm || IS_ERR(pwrdm))
 	if (!pwrdm || IS_ERR(pwrdm))
 		return -EINVAL;
 		return -EINVAL;
@@ -1116,14 +1108,14 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
 		goto osps_out;
 		goto osps_out;
 
 
 	sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
 	sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
-							    pwrst, &hwsup);
+							    pwrst);
 
 
 	ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
 	ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
 	if (ret)
 	if (ret)
 		pr_err("%s: unable to set power state of powerdomain: %s\n",
 		pr_err("%s: unable to set power state of powerdomain: %s\n",
 		       __func__, pwrdm->name);
 		       __func__, pwrdm->name);
 
 
-	_pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup);
+	_pwrdm_restore_clkdm_state(pwrdm, sleep_switch);
 
 
 osps_out:
 osps_out:
 	pwrdm_unlock(pwrdm);
 	pwrdm_unlock(pwrdm);

+ 2 - 1
arch/arm/mach-omap2/timer.c

@@ -289,6 +289,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 	if (!timer->io_base)
 	if (!timer->io_base)
 		return -ENXIO;
 		return -ENXIO;
 
 
+	omap_hwmod_setup_one(oh_name);
+
 	/* After the dmtimer is using hwmod these clocks won't be needed */
 	/* After the dmtimer is using hwmod these clocks won't be needed */
 	timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));
 	timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));
 	if (IS_ERR(timer->fclk))
 	if (IS_ERR(timer->fclk))
@@ -303,7 +305,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 
 
 	clk_put(src);
 	clk_put(src);
 
 
-	omap_hwmod_setup_one(oh_name);
 	omap_hwmod_enable(oh);
 	omap_hwmod_enable(oh);
 	__omap_dm_timer_init_regs(timer);
 	__omap_dm_timer_init_regs(timer);