Skip to contentSkip to conversation

ARM: omap_hwmod: add api to enable/disable module level wakeup

PATCH Superseded Govindraj.R 4 participants 7 messages Apr 24, 2012 – Jun 1, 2012

Subsystems (6)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover ARM: omap_hwmod: add api to enable/disable module level wakeup

From: "Govindraj.R" <[email protected]>

On omap2/3 module level wakeup is handled using PM_WKEN registers. Expand the hwmod framework to handle the module level wakeup enable registers.

Tested on Beagle-xm by enabling and disabling uart wakeups from sysfs Series depends on following patches for testing.
http://marc.info/?l=linux-omap&m=133527588923598&w=2
http://marc.info/?l=linux-omap&m=133518614022144&w=2

Cc Paul Walmsley <[email protected]>
Cc Kevin Hilman <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Tero Kristo <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc Rajendra Nayak <[email protected]>
Cc Santosh Shilimkar <[email protected]>

Govindraj.R (2):
ARM: OMAP2+: omap_hwmod: Add api to enable/disable module level
wakeup events
ARM: omap3: pm: Remove uart module level wakeup configurations

 arch/arm/mach-omap2/omap_hwmod.c   |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/pm34xx.c       |   14 +++++---------
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   16 ++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.h |    9 +++++++++
 4 files changed, 52 insertions(+), 9 deletions(-)
Signature · 1 line
1.7.9
#1 lore raw

PATCH v3 1/2 ARM: OMAP2+: omap_hwmod: Add api to enable/disable module level wakeup events

From: "Govindraj.R" <[email protected]>

On 24xx/34xx/36xx Module level wakeup events are enabled/disabled using PM_WKEN1_CORE/PM_WKEN_PER regs.

Add api to control the module level wakeup mechanism from info provided from hwmod data.

omap_hwmod_enable/disable_wakeup is used from serial.c which should configure PM_WKEN register to enable or disable the module level wakeup.

Cc Tero Kristo <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Kevin Hilman <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Rajendra Nayak <[email protected]>
Cc Santosh Shilimkar <[email protected]>
---
 arch/arm/mach-omap2/omap_hwmod.c   |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   16 ++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.h |    9 +++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +22 -0
index 2c27fdb..4f10619 100644
@@ -382,6 +382,26 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 }
 
 /**
+ * _enable_module_level_wakeup - enable/disable module level wakeup on hwmod.
+ * @oh: struct omap_hwmod *
+ * @set_wake: bool value indicating to set (true) or clear (false) module level
+ *		wakeup enable
+ *
+ * Set or clear the  module level wakeup capability the
+ * hwmod @oh. This function configures th PM_WKEN reg bits if they
+ * are available from hwmod. No return value
+ */
+static void _enable_module_level_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		omap2_prm_enable_prcm_module_wakeup(
+				oh->prcm.omap2.module_offs,
+				oh->prcm.omap2.prcm_reg_id,
+				oh->prcm.omap2.idlest_idle_bit,
+				set_wake);
+}
+
+/**
  * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux
  * @oh: struct omap_hwmod *
  * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
@@ -2471,6 +2491,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 		_write_sysconfig(v, oh);
 	}
 
+	_enable_module_level_wakeup(oh, true);
 	_set_idle_ioring_wakeup(oh, true);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
@@ -2504,6 +2525,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 		_write_sysconfig(v, oh);
 	}
 
+	_enable_module_level_wakeup(oh, false);
 	_set_idle_ioring_wakeup(oh, false);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
arch/arm/mach-omap2/prm2xxx_3xxx.c +16 -0
index 9ce7654..85a753e 100644
@@ -28,6 +28,10 @@
 #include "prm-regbits-24xx.h"
 #include "prm-regbits-34xx.h"
 
+static const u8 pm_wken_offs[] = {
+	PM_WKEN1, OMAP24XX_PM_WKEN2
+};
+
 static const struct omap_prcm_irq omap3_prcm_irqs[] = {
 	OMAP_PRCM_IRQ("wkup",	0,	0),
 	OMAP_PRCM_IRQ("io",	9,	1),
@@ -91,6 +95,18 @@ u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
 	return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
 }
 
+void omap2_prm_enable_prcm_module_wakeup(s16 prcm_mod, u8 prm_reg_id,
+			u8 prm_reg_shift, bool set_wake)
+{
+	if (prm_reg_id && (prm_reg_id <= ARRAY_SIZE(pm_wken_offs))) {
+		if (set_wake)
+			omap2_prm_set_mod_reg_bits(1 << prm_reg_shift,
+				prcm_mod, pm_wken_offs[prm_reg_id - 1]);
+		else
+			omap2_prm_clear_mod_reg_bits(1 << prm_reg_shift,
+				prcm_mod, pm_wken_offs[prm_reg_id - 1]);
+	}
+}
 
 /**
  * omap2_prm_is_hardreset_asserted - read the HW reset line state of
arch/arm/mach-omap2/prm2xxx_3xxx.h +9 -0
index 70ac2a1..49a185a 100644
@@ -289,6 +289,13 @@ static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
 		"not suppose to be used on omap4\n");
 	return 0;
 }
+static inline void omap2_prm_enable_prcm_module_wakeup(s16 prcm_mod,
+		u8 prm_reg_id, u8 prm_reg_shift, bool set_wake)
+{
+	WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+		"not suppose to be used on omap4\n");
+	return 0;
+}
 #else
 /* Power/reset management domain register get/set */
 extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
@@ -297,6 +304,8 @@ extern u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
 extern u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
 extern u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
 extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
+extern void omap2_prm_enable_prcm_module_wakeup(s16 prcm_mod, u8 prm_reg_id,
+			u8 prm_reg_shift, bool set_wake);
 
 /* These omap2_ PRM functions apply to both OMAP2 and 3 */
 extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
Signature · 1 line
1.7.9
maintainer
#2 lore raw

PATCH v3 1/2 ARM: OMAP2+: omap_hwmod: Add api to enable/disable module level wakeup events

Quoted 41 lines · Govindraj.R

From: "Govindraj.R" <[email protected]>

On 24xx/34xx/36xx Module level wakeup events are enabled/disabled using PM_WKEN1_CORE/PM_WKEN_PER regs.

Add api to control the module level wakeup mechanism from info provided from hwmod data.

omap_hwmod_enable/disable_wakeup is used from serial.c which should configure PM_WKEN register to enable or disable the module level wakeup.

Cc Tero Kristo <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Kevin Hilman <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Rajendra Nayak <[email protected]>
Cc Santosh Shilimkar <[email protected]>
---
 arch/arm/mach-omap2/omap_hwmod.c   |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   16 ++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.h |    9 +++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +8 -0
index 2c27fdb..4f10619 100644
@@ -382,6 +382,26 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 }
 
 /**
+ * _enable_module_level_wakeup - enable/disable module level wakeup on hwmod.
+ * @oh: struct omap_hwmod *
+ * @set_wake: bool value indicating to set (true) or clear (false) module level
+ *		wakeup enable
+ *
+ * Set or clear the  module level wakeup capability the
+ * hwmod @oh. This function configures th PM_WKEN reg bits if they
+ * are available from hwmod. No return value

arch/arm/mach-omap2/omap_hwmod.c static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle, · line 402

Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod.c +10 -0
+ */
+static void _enable_module_level_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		omap2_prm_enable_prcm_module_wakeup(
+				oh->prcm.omap2.module_offs,
+				oh->prcm.omap2.prcm_reg_id,
+				oh->prcm.omap2.idlest_idle_bit,
+				set_wake);
+}

Please don't sprinkle cpu_is_omap tests into code that gets called multiple times. Initialize things properly during init instead.

Regards,

Tony

#3 lore raw

PATCH v3 2/2 ARM: omap3: pm: Remove uart module level wakeup configurations

In reply to Govindraj.R

From: "Govindraj.R" <[email protected]>

The uart module level wakeups enabling and disabling are now handled from uart driver itself remove the uart module level configurations from pm code.

Cc Paul Walmsley <[email protected]>
Cc Kevin Hilman <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc Tero Kristo <[email protected]>
Cc Rajendra Nayak <[email protected]>
Cc Santosh Shilimkar <[email protected]>
---
 arch/arm/mach-omap2/pm34xx.c |   14 +++++---------
 1 files changed, 5 insertions(+), 9 deletions(-)
arch/arm/mach-omap2/pm34xx.c +5 -9
index 703bd10..7a19498 100644
@@ -529,8 +529,6 @@ static void __init omap3_d2d_idle(void)
 
 static void __init prcm_setup_regs(void)
 {
-	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;
 
@@ -562,13 +560,11 @@ static void __init prcm_setup_regs(void)
 				OMAP3430_DSS_MOD, PM_WKEN);
 
 	/* Enable wakeups in PER */
-	omap2_prm_write_mod_reg(omap3630_en_uart4_mask |
-			  OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK |
-			  OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK |
-			  OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK |
-			  OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK |
-			  OMAP3430_EN_MCBSP4_MASK,
-			  OMAP3430_PER_MOD, PM_WKEN);
+	omap2_prm_write_mod_reg(OMAP3430_EN_GPIO2_MASK |
+			OMAP3430_EN_GPIO3_MASK | OMAP3430_EN_GPIO4_MASK |
+			OMAP3430_EN_GPIO5_MASK | OMAP3430_EN_GPIO6_MASK |
+			OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK |
+			OMAP3430_EN_MCBSP4_MASK, OMAP3430_PER_MOD, PM_WKEN);
 	/* and allow them to wake up MPU */
 	omap2_prm_write_mod_reg(omap3630_grpsel_uart4_mask |
 			  OMAP3430_GRPSEL_GPIO2_MASK |
Signature · 1 line
1.7.9
#4 lore raw

PATCH v4 1/2 ARM: OMAP2+: omap_hwmod: Add api to enable/disable module level wakeup events

In reply to Govindraj.R

From: "Govindraj.R" <[email protected]>

On 24xx/34xx/36xx Module level wakeup events are enabled/disabled using PM_WKEN1_CORE/PM_WKEN_PER regs.

Add api to control the module level wakeup mechanism from info provided from hwmod data.

omap_hwmod_enable/disable_wakeup is used from serial.c which should configure PM_WKEN register to enable or disable the module level wakeup.

Cc Tero Kristo <[email protected]>
Cc Tony Lindgren <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Kevin Hilman <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Rajendra Nayak <[email protected]>
Cc Santosh Shilimkar <[email protected]>
---
 arch/arm/mach-omap2/omap_hwmod.c   |   23 +++++++++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   16 ++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.h |    9 +++++++++
 3 files changed, 48 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +23 -0
index 2c27fdb..25f306b 100644
@@ -382,6 +382,27 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 }
 
 /**
+ * _enable_module_level_wakeup - enable/disable module level wakeup on hwmod.
+ * @oh: struct omap_hwmod *
+ * @set_wake: bool value indicating to set (true) or clear (false) module level
+ *		wakeup enable
+ *
+ * Set or clear the  module level wakeup capability the
+ * hwmod @oh. This function configures th PM_WKEN reg bits if they
+ * are available from hwmod. No return value
+ */
+static void _enable_module_level_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	if (oh->prcm.omap2.module_offs && oh->prcm.omap2.prcm_reg_id &&
+			oh->prcm.omap2.idlest_idle_bit)
+		omap2_prm_enable_prcm_module_wakeup(
+				oh->prcm.omap2.module_offs,
+				oh->prcm.omap2.prcm_reg_id,
+				oh->prcm.omap2.idlest_idle_bit,
+				set_wake);
+}
+
+/**
  * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux
  * @oh: struct omap_hwmod *
  * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
@@ -2471,6 +2492,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 		_write_sysconfig(v, oh);
 	}
 
+	_enable_module_level_wakeup(oh, true);
 	_set_idle_ioring_wakeup(oh, true);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
@@ -2504,6 +2526,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 		_write_sysconfig(v, oh);
 	}
 
+	_enable_module_level_wakeup(oh, false);
 	_set_idle_ioring_wakeup(oh, false);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
arch/arm/mach-omap2/prm2xxx_3xxx.c +16 -0
index 9ce7654..85a753e 100644
@@ -28,6 +28,10 @@
 #include "prm-regbits-24xx.h"
 #include "prm-regbits-34xx.h"
 
+static const u8 pm_wken_offs[] = {
+	PM_WKEN1, OMAP24XX_PM_WKEN2
+};
+
 static const struct omap_prcm_irq omap3_prcm_irqs[] = {
 	OMAP_PRCM_IRQ("wkup",	0,	0),
 	OMAP_PRCM_IRQ("io",	9,	1),
@@ -91,6 +95,18 @@ u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
 	return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
 }
 
+void omap2_prm_enable_prcm_module_wakeup(s16 prcm_mod, u8 prm_reg_id,
+			u8 prm_reg_shift, bool set_wake)
+{
+	if (prm_reg_id && (prm_reg_id <= ARRAY_SIZE(pm_wken_offs))) {
+		if (set_wake)
+			omap2_prm_set_mod_reg_bits(1 << prm_reg_shift,
+				prcm_mod, pm_wken_offs[prm_reg_id - 1]);
+		else
+			omap2_prm_clear_mod_reg_bits(1 << prm_reg_shift,
+				prcm_mod, pm_wken_offs[prm_reg_id - 1]);
+	}
+}
 
 /**
  * omap2_prm_is_hardreset_asserted - read the HW reset line state of
arch/arm/mach-omap2/prm2xxx_3xxx.h +9 -0
index 70ac2a1..49a185a 100644
@@ -289,6 +289,13 @@ static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
 		"not suppose to be used on omap4\n");
 	return 0;
 }
+static inline void omap2_prm_enable_prcm_module_wakeup(s16 prcm_mod,
+		u8 prm_reg_id, u8 prm_reg_shift, bool set_wake)
+{
+	WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+		"not suppose to be used on omap4\n");
+	return 0;
+}
 #else
 /* Power/reset management domain register get/set */
 extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
@@ -297,6 +304,8 @@ extern u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
 extern u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
 extern u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
 extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
+extern void omap2_prm_enable_prcm_module_wakeup(s16 prcm_mod, u8 prm_reg_id,
+			u8 prm_reg_shift, bool set_wake);
 
 /* These omap2_ PRM functions apply to both OMAP2 and 3 */
 extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
Signature · 1 line
1.7.9
#5 lore raw

PATCH v4 1/2 ARM: OMAP2+: omap_hwmod: Add api to enable/disable module level wakeup events

Quoted 7 lines · Govindraj.R

From: "Govindraj.R" <[email protected]>

On 24xx/34xx/36xx Module level wakeup events are enabled/disabled using PM_WKEN1_CORE/PM_WKEN_PER regs.

Add api to control the module level wakeup mechanism from info provided from hwmod data.

Can you rework this slightly on top of the new SoC detection support
recently added to hwmod[1]. That series adds support for init-time, SoC
specific function pointers for this kind of SoC specific feature.

Kevin

[1] git://git.pwsan.com/linux-2.6 hwmod_soc_conditional_cleanup_3.5

#6 lore raw

PATCH v4 1/2 ARM: OMAP2+: omap_hwmod: Add api to enable/disable module level wakeup events

In reply to Govindraj.R

On Wed, Apr 25, 2012 at 2:17 AM, Govindraj.R <[email protected]> wrote:
[...]

arch/arm/mach-omap2/prm2xxx_3xxx.h static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, · line 297

Quoted 12 lines
arch/arm/mach-omap2/prm2xxx_3xxx.h +6 -0
@@ -289,6 +289,13 @@ static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
 ? ? ? ? ? ? ? ?"not suppose to be used on omap4\n");
 ? ? ? ?return 0;
 ?}
+static inline void omap2_prm_enable_prcm_module_wakeup(s16 prcm_mod,
+ ? ? ? ? ? ? ? u8 prm_reg_id, u8 prm_reg_shift, bool set_wake)
+{
+ ? ? ? WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ ? ? ? ? ? ? ? "not suppose to be used on omap4\n");
+ ? ? ? return 0;

^^^^^ minor comment - we should not return a value in a function returning void

[...]
Regards,
Nishanth Menon