All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv11 0/8] OMAP3+: PRCM chain handler
@ 2011-12-12 18:15 ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

Hi,

PRCM chain handler is adding a support to the omap3+ kernel that
allows different drivers to use PRCM interrupt events for their
own purposes, typically this means IO wakeups. This work was
attempted to integrate as its own driver at some point of
the evolution of this set, however this was now postponed as
the lacking support is basically blocking a few drivers.

This is the version 11 of this set, now posted to linux-arm-kernel also
as cc. Contains just a couple of minor changes compared to previous
version proposed by Kevin Hilman.

Also, patch 8 is new (posted as a separate patch to l-o list earlier),
for supporting different irqs for different pads on the same hwmod.
This is needed at least by USB driver.

This version tested on omap3 beagle board, dynamic idle + suspend,
with and without off-mode. I have pushed two branches on a public
git tree:

git://gitorious.org/~kristo/omap-pm/omap-pm-work.git

branch: chain-prcm-v11
branch2: chain-prcm-v11-debug

Debug branch contains a few debugging related patches I've used
for testing purposes.

-Tero


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 0/8] OMAP3+: PRCM chain handler
@ 2011-12-12 18:15 ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

PRCM chain handler is adding a support to the omap3+ kernel that
allows different drivers to use PRCM interrupt events for their
own purposes, typically this means IO wakeups. This work was
attempted to integrate as its own driver at some point of
the evolution of this set, however this was now postponed as
the lacking support is basically blocking a few drivers.

This is the version 11 of this set, now posted to linux-arm-kernel also
as cc. Contains just a couple of minor changes compared to previous
version proposed by Kevin Hilman.

Also, patch 8 is new (posted as a separate patch to l-o list earlier),
for supporting different irqs for different pads on the same hwmod.
This is needed at least by USB driver.

This version tested on omap3 beagle board, dynamic idle + suspend,
with and without off-mode. I have pushed two branches on a public
git tree:

git://gitorious.org/~kristo/omap-pm/omap-pm-work.git

branch: chain-prcm-v11
branch2: chain-prcm-v11-debug

Debug branch contains a few debugging related patches I've used
for testing purposes.

-Tero

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel, R, Govindraj

From: R, Govindraj <govindraj.raja@ti.com>

Add API to enable IO pad wakeup capability based on mux dynamic pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability
for the given pads. Wakeup capability will be enabled/disabled
during hwmod idle transition based on whether wakeup_flag is
set or cleared.

Map the enable/disable pad wakeup API's to hwmod_wakeup_enable/disable.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   59 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6b3088d..8d37d83 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2059,6 +2059,34 @@ static int __init omap_hwmod_setup_all(void)
 core_initcall(omap_hwmod_setup_all);
 
 /**
+ * omap_hwmod_set_ioring_wakeup - enable io pad wakeup flag.
+ * @oh: struct omap_hwmod *
+ * @set: bool value indicating to set or clear wakeup status.
+ *
+ * Set or Clear wakeup flag for the io_pad.
+ */
+static int omap_hwmod_set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	struct omap_device_pad *pad;
+	int ret = -EINVAL, j;
+
+	if (oh->mux && oh->mux->enabled) {
+		for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+			pad = oh->mux->pads_dynamic[j];
+			if (pad->flags & OMAP_DEVICE_PAD_WAKEUP) {
+				if (set_wake)
+					pad->idle |= OMAP_WAKEUP_EN;
+				else
+					pad->idle &= ~OMAP_WAKEUP_EN;
+				ret = 0;
+			}
+		}
+	}
+
+	return ret;
+}
+
+/**
  * omap_hwmod_enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
@@ -2390,6 +2418,35 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
 {
 	return _del_initiator_dep(oh, init_oh);
 }
+/**
+ * omap_hwmod_enable_ioring_wakeup - Set wakeup flag for iopad.
+ * @oh: struct omap_hwmod *
+ *
+ * Traverse through dynamic pads, if pad is enabled then
+ * set wakeup enable bit flag for the mux pin. Wakeup pad bit
+ * will be set during hwmod idle transistion.
+ * Return error if pads are not enabled or not available.
+ */
+int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh)
+{
+	/* Enable pad wake-up capability */
+	return omap_hwmod_set_ioring_wakeup(oh, true);
+}
+
+/**
+ * omap_hwmod_disable_ioring_wakeup - Clear wakeup flag for iopad.
+ * @oh: struct omap_hwmod *
+ *
+ * Traverse through dynamic pads, if pad is enabled then
+ * clear wakeup enable bit flag for the mux pin. Wakeup pad bit
+ * will be set during hwmod idle transistion.
+ * Return error if pads are not enabled or not available.
+ */
+int omap_hwmod_disable_ioring_wakeup(struct omap_hwmod *oh)
+{
+	/* Disable pad wakeup capability */
+	return omap_hwmod_set_ioring_wakeup(oh, false);
+}
 
 /**
  * omap_hwmod_enable_wakeup - allow device to wake up the system
@@ -2416,6 +2473,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_enable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	omap_hwmod_enable_ioring_wakeup(oh);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
@@ -2446,6 +2504,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_disable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	omap_hwmod_disable_ioring_wakeup(oh);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

From: R, Govindraj <govindraj.raja@ti.com>

Add API to enable IO pad wakeup capability based on mux dynamic pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability
for the given pads. Wakeup capability will be enabled/disabled
during hwmod idle transition based on whether wakeup_flag is
set or cleared.

Map the enable/disable pad wakeup API's to hwmod_wakeup_enable/disable.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   59 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6b3088d..8d37d83 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2059,6 +2059,34 @@ static int __init omap_hwmod_setup_all(void)
 core_initcall(omap_hwmod_setup_all);
 
 /**
+ * omap_hwmod_set_ioring_wakeup - enable io pad wakeup flag.
+ * @oh: struct omap_hwmod *
+ * @set: bool value indicating to set or clear wakeup status.
+ *
+ * Set or Clear wakeup flag for the io_pad.
+ */
+static int omap_hwmod_set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	struct omap_device_pad *pad;
+	int ret = -EINVAL, j;
+
+	if (oh->mux && oh->mux->enabled) {
+		for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+			pad = oh->mux->pads_dynamic[j];
+			if (pad->flags & OMAP_DEVICE_PAD_WAKEUP) {
+				if (set_wake)
+					pad->idle |= OMAP_WAKEUP_EN;
+				else
+					pad->idle &= ~OMAP_WAKEUP_EN;
+				ret = 0;
+			}
+		}
+	}
+
+	return ret;
+}
+
+/**
  * omap_hwmod_enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
@@ -2390,6 +2418,35 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
 {
 	return _del_initiator_dep(oh, init_oh);
 }
+/**
+ * omap_hwmod_enable_ioring_wakeup - Set wakeup flag for iopad.
+ * @oh: struct omap_hwmod *
+ *
+ * Traverse through dynamic pads, if pad is enabled then
+ * set wakeup enable bit flag for the mux pin. Wakeup pad bit
+ * will be set during hwmod idle transistion.
+ * Return error if pads are not enabled or not available.
+ */
+int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh)
+{
+	/* Enable pad wake-up capability */
+	return omap_hwmod_set_ioring_wakeup(oh, true);
+}
+
+/**
+ * omap_hwmod_disable_ioring_wakeup - Clear wakeup flag for iopad.
+ * @oh: struct omap_hwmod *
+ *
+ * Traverse through dynamic pads, if pad is enabled then
+ * clear wakeup enable bit flag for the mux pin. Wakeup pad bit
+ * will be set during hwmod idle transistion.
+ * Return error if pads are not enabled or not available.
+ */
+int omap_hwmod_disable_ioring_wakeup(struct omap_hwmod *oh)
+{
+	/* Disable pad wakeup capability */
+	return omap_hwmod_set_ioring_wakeup(oh, false);
+}
 
 /**
  * omap_hwmod_enable_wakeup - allow device to wake up the system
@@ -2416,6 +2473,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_enable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	omap_hwmod_enable_ioring_wakeup(oh);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
@@ -2446,6 +2504,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_disable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	omap_hwmod_disable_ioring_wakeup(oh);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel, R, Govindraj

From: R, Govindraj <govindraj.raja@ti.com>

Add API to determine IO-PAD wakeup event status for a given
hwmod dynamic_mux pad.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/mux.c                    |   30 ++++++++++++++++++++++++++
 arch/arm/mach-omap2/mux.h                    |   13 +++++++++++
 arch/arm/mach-omap2/omap_hwmod.c             |    7 ++++++
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    1 +
 4 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 655e948..5f15ab8 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -351,6 +351,36 @@ err1:
 	return NULL;
 }
 
+/**
+ * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
+ * @hmux:		Pads for a hwmod
+ *
+ * Gets the wakeup status of given pad from omap-hwmod.
+ * Returns true if wakeup event is set for pad else false
+ * if wakeup is not occured or pads are not avialable.
+ */
+bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
+{
+	int i;
+	unsigned int val;
+	u8 ret = false;
+
+	for (i = 0; i < hmux->nr_pads; i++) {
+		struct omap_device_pad *pad = &hmux->pads[i];
+
+		if (pad->flags & OMAP_DEVICE_PAD_WAKEUP) {
+			val = omap_mux_read(pad->partition,
+					pad->mux->reg_offset);
+			if (val & OMAP_WAKEUP_EVENT) {
+				ret = true;
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
 /* Assumes the calling function takes care of locking */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
 {
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 2132308..8b2150a 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -225,8 +225,21 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
  */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
 
+/**
+ * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
+ * @hmux:		Pads for a hwmod
+ *
+ * Called only from omap_hwmod.c, do not use.
+ */
+bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux);
 #else
 
+static inline bool
+omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
+{
+	return 0;
+}
+
 static inline int omap_mux_init_gpio(int gpio, int val)
 {
 	return 0;
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 8d37d83..d7f4623 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2721,3 +2721,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
 
 	return 0;
 }
+
+int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
+{
+	if (oh && oh->mux)
+		return omap_hwmod_mux_get_wake_status(oh->mux);
+	return -EINVAL;
+}
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 8b372ed..1b81dfb 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -604,6 +604,7 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
 
+int omap_hwmod_pad_get_wakeup_status(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
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

From: R, Govindraj <govindraj.raja@ti.com>

Add API to determine IO-PAD wakeup event status for a given
hwmod dynamic_mux pad.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/mux.c                    |   30 ++++++++++++++++++++++++++
 arch/arm/mach-omap2/mux.h                    |   13 +++++++++++
 arch/arm/mach-omap2/omap_hwmod.c             |    7 ++++++
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    1 +
 4 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 655e948..5f15ab8 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -351,6 +351,36 @@ err1:
 	return NULL;
 }
 
+/**
+ * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
+ * @hmux:		Pads for a hwmod
+ *
+ * Gets the wakeup status of given pad from omap-hwmod.
+ * Returns true if wakeup event is set for pad else false
+ * if wakeup is not occured or pads are not avialable.
+ */
+bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
+{
+	int i;
+	unsigned int val;
+	u8 ret = false;
+
+	for (i = 0; i < hmux->nr_pads; i++) {
+		struct omap_device_pad *pad = &hmux->pads[i];
+
+		if (pad->flags & OMAP_DEVICE_PAD_WAKEUP) {
+			val = omap_mux_read(pad->partition,
+					pad->mux->reg_offset);
+			if (val & OMAP_WAKEUP_EVENT) {
+				ret = true;
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
 /* Assumes the calling function takes care of locking */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
 {
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 2132308..8b2150a 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -225,8 +225,21 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
  */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
 
+/**
+ * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
+ * @hmux:		Pads for a hwmod
+ *
+ * Called only from omap_hwmod.c, do not use.
+ */
+bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux);
 #else
 
+static inline bool
+omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
+{
+	return 0;
+}
+
 static inline int omap_mux_init_gpio(int gpio, int val)
 {
 	return 0;
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 8d37d83..d7f4623 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2721,3 +2721,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
 
 	return 0;
 }
+
+int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
+{
+	if (oh && oh->mux)
+		return omap_hwmod_mux_get_wake_status(oh->mux);
+	return -EINVAL;
+}
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 8b372ed..1b81dfb 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -604,6 +604,7 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
 
+int omap_hwmod_pad_get_wakeup_status(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
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 3/8] ARM: OMAP: prm: add support for chain interrupt handler
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap
  Cc: linux-arm-kernel, Paul Walmsley, Kevin Hilman, Avinash.H.M,
	Cousson, Benoit, Tony Lindgren, Govindraj.R

Introduce a chained interrupt handler mechanism for the PRCM
interrupt, so that individual PRCM event can cleanly be handled by
handlers in separate drivers. We do this by introducing PRCM event
names, which are then matched to the particular PRCM interrupt bit
depending on the specific OMAP SoC being used.

PRCM interrupts have two priority levels, high or normal. High priority
is needed for IO event handling, so that we can be sure that IO events
are processed before other events. This reduces latency for IO event
customers and also prevents incorrect ack sequence on OMAP3.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Avinash.H.M <avinashhm@ti.com>
Cc: Cousson, Benoit <b-cousson@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/prcm-common.h  |   29 +++++
 arch/arm/mach-omap2/prcm.c         |  229 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   21 ++++
 arch/arm/mach-omap2/prm44xx.c      |   21 ++++
 4 files changed, 300 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 0363dcb..3c54e3c 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -408,6 +408,35 @@
 extern void __iomem *prm_base;
 extern void __iomem *cm_base;
 extern void __iomem *cm2_base;
+
+struct omap_prcm_irq {
+	const char *name;
+	unsigned int offset;
+	bool priority;
+};
+
+struct omap_prcm_irq_setup {
+	u32 ack;
+	u32 mask;
+	int nr_regs;
+	int nr_irqs;
+	const struct omap_prcm_irq *irqs;
+	u32 *saved_mask;
+	u32 *priority_mask;
+	int base_irq;
+	int irq;
+};
+
+#define OMAP_PRCM_IRQ(_name, _offset, _priority) {	\
+	.name = _name,					\
+	.offset = _offset,				\
+	.priority = _priority				\
+	}
+
+extern void omap_prcm_irq_cleanup(void);
+extern int omap_prcm_register_chain_handler(
+	struct omap_prcm_irq_setup *irq_setup);
+extern int omap_prcm_event_to_irq(const char *event);
 # endif
 
 #endif
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 597e2da..948247f 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -24,6 +24,9 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <mach/system.h>
 #include <plat/common.h>
@@ -45,6 +48,10 @@ void __iomem *cm_base;
 void __iomem *cm2_base;
 
 #define MAX_MODULE_ENABLE_WAIT		100000
+#define OMAP_PRCM_MAX_NR_PENDING_REG	2
+
+static struct irq_chip_generic **prcm_irq_chips;
+static struct omap_prcm_irq_setup *prcm_irq_setup;
 
 u32 omap_prcm_get_reset_sources(void)
 {
@@ -159,3 +166,225 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
 	if (omap2_globals->cm2)
 		cm2_base = omap2_globals->cm2;
 }
+
+static inline u32 prcm_irq_read_reg(int offset)
+{
+	return __raw_readl(prm_base + offset);
+}
+
+static inline void prcm_irq_write_reg(u32 value, int offset)
+{
+	__raw_writel(value, prm_base + offset);
+}
+
+static void omap_prm_pending_events(unsigned long *events)
+{
+	u32 mask, st;
+	int i;
+
+	memset(events, 0, prcm_irq_setup->nr_regs * sizeof(unsigned long));
+
+	for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+		mask = prcm_irq_read_reg(prcm_irq_setup->mask + i * 4);
+		st = prcm_irq_read_reg(prcm_irq_setup->ack + i * 4);
+		events[i] = mask & st;
+	}
+}
+
+/*
+ * Move priority events from events to priority_events array
+ */
+static void omap_prm_events_filter_priority(unsigned long *events,
+	unsigned long *priority_events)
+{
+	int i;
+
+	for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+		priority_events[i] =
+			events[i] & prcm_irq_setup->priority_mask[i];
+		events[i] ^= priority_events[i];
+	}
+}
+
+/*
+ * PRCM Interrupt Handler
+ *
+ * This is a common handler for the OMAP PRCM interrupts. Pending
+ * interrupts are detected by a call to prm_pending_events and
+ * dispatched accordingly. Clearing of the wakeup events should be
+ * done by the SoC specific individual handlers.
+ */
+static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
+	unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	unsigned int virtirq;
+	int nr_irqs = prcm_irq_setup->nr_regs * 32;
+
+	/*
+	 * Loop until all pending irqs are handled, since
+	 * generic_handle_irq() can cause new irqs to come
+	 */
+	while (1) {
+		omap_prm_pending_events(pending);
+
+		/* No bit set, then all IRQs are handled */
+		if (find_first_bit(pending, nr_irqs) >= nr_irqs)
+			break;
+
+		omap_prm_events_filter_priority(pending, priority_pending);
+
+		/*
+		 * Loop on all currently pending irqs so that new irqs
+		 * cannot starve previously pending irqs
+		 */
+
+		/* Serve priority events first */
+		for_each_set_bit(virtirq, priority_pending, nr_irqs)
+			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
+
+		/* Serve normal events next */
+		for_each_set_bit(virtirq, pending, nr_irqs)
+			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
+	}
+	if (chip->irq_ack)
+		chip->irq_ack(&desc->irq_data);
+	if (chip->irq_eoi)
+		chip->irq_eoi(&desc->irq_data);
+	chip->irq_unmask(&desc->irq_data);
+}
+
+/*
+ * Given a PRCM event name, returns the corresponding IRQ on which the
+ * handler should be registered.
+ */
+int omap_prcm_event_to_irq(const char *name)
+{
+	int i;
+
+	if (!prcm_irq_setup)
+		return -ENOENT;
+
+	for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
+		if (!strcmp(prcm_irq_setup->irqs[i].name, name))
+			return prcm_irq_setup->base_irq +
+				prcm_irq_setup->irqs[i].offset;
+
+	return -ENOENT;
+}
+
+/*
+ * Reverses memory allocated and other steps done by
+ * omap_prcm_register_chain_handler
+ */
+void omap_prcm_irq_cleanup(void)
+{
+	int i;
+
+	if (prcm_irq_chips) {
+		for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+			if (prcm_irq_chips[i])
+				irq_remove_generic_chip(prcm_irq_chips[i],
+					0xffffffff, 0, 0);
+			prcm_irq_chips[i] = NULL;
+		}
+		kfree(prcm_irq_chips);
+		prcm_irq_chips = NULL;
+	}
+
+	kfree(prcm_irq_setup->saved_mask);
+	prcm_irq_setup->saved_mask = NULL;
+
+	kfree(prcm_irq_setup->priority_mask);
+	prcm_irq_setup->priority_mask = NULL;
+
+	irq_set_chained_handler(prcm_irq_setup->irq, NULL);
+
+	if (prcm_irq_setup->base_irq > 0)
+		irq_free_descs(prcm_irq_setup->base_irq,
+			prcm_irq_setup->nr_regs * 32);
+	prcm_irq_setup->base_irq = 0;
+}
+
+/*
+ * Initializes the prcm chain handler based on provided parameters
+ */
+int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
+{
+	int nr_regs = irq_setup->nr_regs;
+	u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
+	int offset;
+	int max_irq = 0;
+	int i;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+
+	if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
+		pr_err("PRCM: nr_regs too large\n");
+	goto err;
+	}
+
+	prcm_irq_setup = irq_setup;
+
+	prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
+	prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
+	prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
+		GFP_KERNEL);
+
+	if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
+	    !prcm_irq_setup->priority_mask) {
+		pr_err("PRCM: kzalloc failed\n");
+		goto err;
+	}
+
+	memset(mask, 0, sizeof(mask));
+
+	for (i = 0; i < irq_setup->nr_irqs; i++) {
+		offset = irq_setup->irqs[i].offset;
+		mask[offset >> 5] |= 1 << (offset & 0x1f);
+		if (offset > max_irq)
+			max_irq = offset;
+		if (irq_setup->irqs[i].priority)
+			irq_setup->priority_mask[offset >> 5] |=
+				1 << (offset & 0x1f);
+	}
+
+	irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
+
+	irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
+		0);
+
+	if (irq_setup->base_irq < 0) {
+		pr_err("PRCM: failed to allocate irq descs: %d\n",
+			irq_setup->base_irq);
+		goto err;
+	}
+
+	for (i = 0; i <= irq_setup->nr_regs; i++) {
+		gc = irq_alloc_generic_chip("PRCM", 1,
+			irq_setup->base_irq + i * 32, prm_base,
+			handle_level_irq);
+
+		if (!gc) {
+			pr_err("PRCM: failed to allocate generic chip\n");
+			goto err;
+		}
+		ct = gc->chip_types;
+		ct->chip.irq_ack = irq_gc_ack_set_bit;
+		ct->chip.irq_mask = irq_gc_mask_clr_bit;
+		ct->chip.irq_unmask = irq_gc_mask_set_bit;
+
+		ct->regs.ack = irq_setup->ack + i * 4;
+		ct->regs.mask = irq_setup->mask + i * 4;
+
+		irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
+		prcm_irq_chips[i] = gc;
+	}
+
+	return 0;
+
+err:
+	omap_prcm_irq_cleanup();
+	return -ENOMEM;
+}
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index f02d87f..9f1aad3 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -27,6 +27,20 @@
 #include "prm-regbits-24xx.h"
 #include "prm-regbits-34xx.h"
 
+static const struct omap_prcm_irq omap3_prcm_irqs[] = {
+	OMAP_PRCM_IRQ("wkup",	0,	0),
+	OMAP_PRCM_IRQ("io",	9,	1),
+};
+
+static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
+	.ack		= OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+	.mask		= OMAP3_PRM_IRQENABLE_MPU_OFFSET,
+	.nr_regs	= 1,
+	.irqs		= omap3_prcm_irqs,
+	.nr_irqs	= ARRAY_SIZE(omap3_prcm_irqs),
+	.irq		= INT_34XX_PRCM_MPU_IRQ,
+};
+
 u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
 {
 	return __raw_readl(prm_base + module + idx);
@@ -212,3 +226,10 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
 {
 	return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
 }
+
+static int __init omap3xxx_prcm_init(void)
+{
+	if (cpu_is_omap34xx())
+		return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 495a31a..17614f7 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -27,6 +27,20 @@
 #include "prcm44xx.h"
 #include "prminst44xx.h"
 
+static const struct omap_prcm_irq omap4_prcm_irqs[] = {
+	OMAP_PRCM_IRQ("wkup",   0,      0),
+	OMAP_PRCM_IRQ("io",     9,      1),
+};
+
+static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
+	.ack		= OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+	.mask		= OMAP4_PRM_IRQENABLE_MPU_OFFSET,
+	.nr_regs	= 2,
+	.irqs		= omap4_prcm_irqs,
+	.nr_irqs	= ARRAY_SIZE(omap4_prcm_irqs),
+	.irq		= OMAP44XX_IRQ_PRCM,
+};
+
 /* PRM low-level functions */
 
 /* Read a register in a CM/PRM instance in the PRM module */
@@ -121,3 +135,10 @@ u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
 					       OMAP4430_PRM_DEVICE_INST,
 					       offset);
 }
+
+static int __init omap4xxx_prcm_init(void)
+{
+	if (cpu_is_omap44xx())
+		return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+	return 0;
+}
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 3/8] ARM: OMAP: prm: add support for chain interrupt handler
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce a chained interrupt handler mechanism for the PRCM
interrupt, so that individual PRCM event can cleanly be handled by
handlers in separate drivers. We do this by introducing PRCM event
names, which are then matched to the particular PRCM interrupt bit
depending on the specific OMAP SoC being used.

PRCM interrupts have two priority levels, high or normal. High priority
is needed for IO event handling, so that we can be sure that IO events
are processed before other events. This reduces latency for IO event
customers and also prevents incorrect ack sequence on OMAP3.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Avinash.H.M <avinashhm@ti.com>
Cc: Cousson, Benoit <b-cousson@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/prcm-common.h  |   29 +++++
 arch/arm/mach-omap2/prcm.c         |  229 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   21 ++++
 arch/arm/mach-omap2/prm44xx.c      |   21 ++++
 4 files changed, 300 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 0363dcb..3c54e3c 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -408,6 +408,35 @@
 extern void __iomem *prm_base;
 extern void __iomem *cm_base;
 extern void __iomem *cm2_base;
+
+struct omap_prcm_irq {
+	const char *name;
+	unsigned int offset;
+	bool priority;
+};
+
+struct omap_prcm_irq_setup {
+	u32 ack;
+	u32 mask;
+	int nr_regs;
+	int nr_irqs;
+	const struct omap_prcm_irq *irqs;
+	u32 *saved_mask;
+	u32 *priority_mask;
+	int base_irq;
+	int irq;
+};
+
+#define OMAP_PRCM_IRQ(_name, _offset, _priority) {	\
+	.name = _name,					\
+	.offset = _offset,				\
+	.priority = _priority				\
+	}
+
+extern void omap_prcm_irq_cleanup(void);
+extern int omap_prcm_register_chain_handler(
+	struct omap_prcm_irq_setup *irq_setup);
+extern int omap_prcm_event_to_irq(const char *event);
 # endif
 
 #endif
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 597e2da..948247f 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -24,6 +24,9 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <mach/system.h>
 #include <plat/common.h>
@@ -45,6 +48,10 @@ void __iomem *cm_base;
 void __iomem *cm2_base;
 
 #define MAX_MODULE_ENABLE_WAIT		100000
+#define OMAP_PRCM_MAX_NR_PENDING_REG	2
+
+static struct irq_chip_generic **prcm_irq_chips;
+static struct omap_prcm_irq_setup *prcm_irq_setup;
 
 u32 omap_prcm_get_reset_sources(void)
 {
@@ -159,3 +166,225 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
 	if (omap2_globals->cm2)
 		cm2_base = omap2_globals->cm2;
 }
+
+static inline u32 prcm_irq_read_reg(int offset)
+{
+	return __raw_readl(prm_base + offset);
+}
+
+static inline void prcm_irq_write_reg(u32 value, int offset)
+{
+	__raw_writel(value, prm_base + offset);
+}
+
+static void omap_prm_pending_events(unsigned long *events)
+{
+	u32 mask, st;
+	int i;
+
+	memset(events, 0, prcm_irq_setup->nr_regs * sizeof(unsigned long));
+
+	for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+		mask = prcm_irq_read_reg(prcm_irq_setup->mask + i * 4);
+		st = prcm_irq_read_reg(prcm_irq_setup->ack + i * 4);
+		events[i] = mask & st;
+	}
+}
+
+/*
+ * Move priority events from events to priority_events array
+ */
+static void omap_prm_events_filter_priority(unsigned long *events,
+	unsigned long *priority_events)
+{
+	int i;
+
+	for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+		priority_events[i] =
+			events[i] & prcm_irq_setup->priority_mask[i];
+		events[i] ^= priority_events[i];
+	}
+}
+
+/*
+ * PRCM Interrupt Handler
+ *
+ * This is a common handler for the OMAP PRCM interrupts. Pending
+ * interrupts are detected by a call to prm_pending_events and
+ * dispatched accordingly. Clearing of the wakeup events should be
+ * done by the SoC specific individual handlers.
+ */
+static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
+	unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	unsigned int virtirq;
+	int nr_irqs = prcm_irq_setup->nr_regs * 32;
+
+	/*
+	 * Loop until all pending irqs are handled, since
+	 * generic_handle_irq() can cause new irqs to come
+	 */
+	while (1) {
+		omap_prm_pending_events(pending);
+
+		/* No bit set, then all IRQs are handled */
+		if (find_first_bit(pending, nr_irqs) >= nr_irqs)
+			break;
+
+		omap_prm_events_filter_priority(pending, priority_pending);
+
+		/*
+		 * Loop on all currently pending irqs so that new irqs
+		 * cannot starve previously pending irqs
+		 */
+
+		/* Serve priority events first */
+		for_each_set_bit(virtirq, priority_pending, nr_irqs)
+			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
+
+		/* Serve normal events next */
+		for_each_set_bit(virtirq, pending, nr_irqs)
+			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
+	}
+	if (chip->irq_ack)
+		chip->irq_ack(&desc->irq_data);
+	if (chip->irq_eoi)
+		chip->irq_eoi(&desc->irq_data);
+	chip->irq_unmask(&desc->irq_data);
+}
+
+/*
+ * Given a PRCM event name, returns the corresponding IRQ on which the
+ * handler should be registered.
+ */
+int omap_prcm_event_to_irq(const char *name)
+{
+	int i;
+
+	if (!prcm_irq_setup)
+		return -ENOENT;
+
+	for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
+		if (!strcmp(prcm_irq_setup->irqs[i].name, name))
+			return prcm_irq_setup->base_irq +
+				prcm_irq_setup->irqs[i].offset;
+
+	return -ENOENT;
+}
+
+/*
+ * Reverses memory allocated and other steps done by
+ * omap_prcm_register_chain_handler
+ */
+void omap_prcm_irq_cleanup(void)
+{
+	int i;
+
+	if (prcm_irq_chips) {
+		for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+			if (prcm_irq_chips[i])
+				irq_remove_generic_chip(prcm_irq_chips[i],
+					0xffffffff, 0, 0);
+			prcm_irq_chips[i] = NULL;
+		}
+		kfree(prcm_irq_chips);
+		prcm_irq_chips = NULL;
+	}
+
+	kfree(prcm_irq_setup->saved_mask);
+	prcm_irq_setup->saved_mask = NULL;
+
+	kfree(prcm_irq_setup->priority_mask);
+	prcm_irq_setup->priority_mask = NULL;
+
+	irq_set_chained_handler(prcm_irq_setup->irq, NULL);
+
+	if (prcm_irq_setup->base_irq > 0)
+		irq_free_descs(prcm_irq_setup->base_irq,
+			prcm_irq_setup->nr_regs * 32);
+	prcm_irq_setup->base_irq = 0;
+}
+
+/*
+ * Initializes the prcm chain handler based on provided parameters
+ */
+int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
+{
+	int nr_regs = irq_setup->nr_regs;
+	u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
+	int offset;
+	int max_irq = 0;
+	int i;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+
+	if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
+		pr_err("PRCM: nr_regs too large\n");
+	goto err;
+	}
+
+	prcm_irq_setup = irq_setup;
+
+	prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
+	prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
+	prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
+		GFP_KERNEL);
+
+	if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
+	    !prcm_irq_setup->priority_mask) {
+		pr_err("PRCM: kzalloc failed\n");
+		goto err;
+	}
+
+	memset(mask, 0, sizeof(mask));
+
+	for (i = 0; i < irq_setup->nr_irqs; i++) {
+		offset = irq_setup->irqs[i].offset;
+		mask[offset >> 5] |= 1 << (offset & 0x1f);
+		if (offset > max_irq)
+			max_irq = offset;
+		if (irq_setup->irqs[i].priority)
+			irq_setup->priority_mask[offset >> 5] |=
+				1 << (offset & 0x1f);
+	}
+
+	irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
+
+	irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
+		0);
+
+	if (irq_setup->base_irq < 0) {
+		pr_err("PRCM: failed to allocate irq descs: %d\n",
+			irq_setup->base_irq);
+		goto err;
+	}
+
+	for (i = 0; i <= irq_setup->nr_regs; i++) {
+		gc = irq_alloc_generic_chip("PRCM", 1,
+			irq_setup->base_irq + i * 32, prm_base,
+			handle_level_irq);
+
+		if (!gc) {
+			pr_err("PRCM: failed to allocate generic chip\n");
+			goto err;
+		}
+		ct = gc->chip_types;
+		ct->chip.irq_ack = irq_gc_ack_set_bit;
+		ct->chip.irq_mask = irq_gc_mask_clr_bit;
+		ct->chip.irq_unmask = irq_gc_mask_set_bit;
+
+		ct->regs.ack = irq_setup->ack + i * 4;
+		ct->regs.mask = irq_setup->mask + i * 4;
+
+		irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
+		prcm_irq_chips[i] = gc;
+	}
+
+	return 0;
+
+err:
+	omap_prcm_irq_cleanup();
+	return -ENOMEM;
+}
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index f02d87f..9f1aad3 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -27,6 +27,20 @@
 #include "prm-regbits-24xx.h"
 #include "prm-regbits-34xx.h"
 
+static const struct omap_prcm_irq omap3_prcm_irqs[] = {
+	OMAP_PRCM_IRQ("wkup",	0,	0),
+	OMAP_PRCM_IRQ("io",	9,	1),
+};
+
+static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
+	.ack		= OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+	.mask		= OMAP3_PRM_IRQENABLE_MPU_OFFSET,
+	.nr_regs	= 1,
+	.irqs		= omap3_prcm_irqs,
+	.nr_irqs	= ARRAY_SIZE(omap3_prcm_irqs),
+	.irq		= INT_34XX_PRCM_MPU_IRQ,
+};
+
 u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
 {
 	return __raw_readl(prm_base + module + idx);
@@ -212,3 +226,10 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
 {
 	return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
 }
+
+static int __init omap3xxx_prcm_init(void)
+{
+	if (cpu_is_omap34xx())
+		return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 495a31a..17614f7 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -27,6 +27,20 @@
 #include "prcm44xx.h"
 #include "prminst44xx.h"
 
+static const struct omap_prcm_irq omap4_prcm_irqs[] = {
+	OMAP_PRCM_IRQ("wkup",   0,      0),
+	OMAP_PRCM_IRQ("io",     9,      1),
+};
+
+static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
+	.ack		= OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+	.mask		= OMAP4_PRM_IRQENABLE_MPU_OFFSET,
+	.nr_regs	= 2,
+	.irqs		= omap4_prcm_irqs,
+	.nr_irqs	= ARRAY_SIZE(omap4_prcm_irqs),
+	.irq		= OMAP44XX_IRQ_PRCM,
+};
+
 /* PRM low-level functions */
 
 /* Read a register in a CM/PRM instance in the PRM module */
@@ -121,3 +135,10 @@ u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
 					       OMAP4430_PRM_DEVICE_INST,
 					       offset);
 }
+
+static int __init omap4xxx_prcm_init(void)
+{
+	if (cpu_is_omap44xx())
+		return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+	return 0;
+}
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 4/8] ARM: OMAP: prcm: add suspend prepare / finish support
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel, Kevin Hilman, Paul Walmsley

PRCM chain handler needs to disable forwarding of interrupts during
suspend, because runtime PM is disabled and most of the drivers
are potentially not able to handle interrupts coming at this time.

This patch masks all the PRCM interrupt events if a PRCM interrupt
occurs during suspend, but does not ack them. Once suspend finish
is called, all the masked events will be re-enabled, which causes
immediate PRCM interrupt and handles the postponed event.

The suspend prepare and complete  callbacks will be called from
pm34xx.c / pm44xx.c files in the following patches.

The functions defined in this patch should eventually be moved to
suspend->prepare and suspend->finish driver hooks, once the PRCM
chain handler will be made as its own driver.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/prcm-common.h |    4 +++
 arch/arm/mach-omap2/prcm.c        |   46 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 3c54e3c..6cb0daf 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -425,6 +425,8 @@ struct omap_prcm_irq_setup {
 	u32 *priority_mask;
 	int base_irq;
 	int irq;
+	bool suspended;
+	bool suspend_save_flag;
 };
 
 #define OMAP_PRCM_IRQ(_name, _offset, _priority) {	\
@@ -437,6 +439,8 @@ extern void omap_prcm_irq_cleanup(void);
 extern int omap_prcm_register_chain_handler(
 	struct omap_prcm_irq_setup *irq_setup);
 extern int omap_prcm_event_to_irq(const char *event);
+extern void omap_prcm_irq_prepare(void);
+extern void omap_prcm_irq_complete(void);
 # endif
 
 #endif
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 948247f..e7c8f3f 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -221,12 +221,28 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	unsigned int virtirq;
 	int nr_irqs = prcm_irq_setup->nr_regs * 32;
+	int i;
+
+	/*
+	 * If we are suspended, mask all interrupts from PRCM level,
+	 * this does not ack them, and they will be pending until
+	 * we re-enable the interrupts, at which point the
+	 * omap_prcm_irq_handler will be executed again
+	 */
+	if (prcm_irq_setup->suspended) {
+		for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+			prcm_irq_setup->saved_mask[i] =
+				prcm_irq_read_reg(prcm_irq_setup->mask + i * 4);
+			prcm_irq_write_reg(0, prcm_irq_setup->mask + i * 4);
+		}
+		prcm_irq_setup->suspend_save_flag = true;
+	}
 
 	/*
 	 * Loop until all pending irqs are handled, since
 	 * generic_handle_irq() can cause new irqs to come
 	 */
-	while (1) {
+	while (!prcm_irq_setup->suspended) {
 		omap_prm_pending_events(pending);
 
 		/* No bit set, then all IRQs are handled */
@@ -307,6 +323,34 @@ void omap_prcm_irq_cleanup(void)
 	prcm_irq_setup->base_irq = 0;
 }
 
+void omap_prcm_irq_prepare(void)
+{
+	prcm_irq_setup->suspended = true;
+}
+
+void omap_prcm_irq_complete(void)
+{
+	int i;
+
+	prcm_irq_setup->suspended = false;
+
+	/* If we have not saved the masks, do not attempt to restore */
+	if (!prcm_irq_setup->suspend_save_flag)
+		return;
+
+	prcm_irq_setup->suspend_save_flag = false;
+
+	/*
+	 * Re-enable all masked PRCM irq sources, this
+	 * causes the PRCM interrupt to fire immediately
+	 * if the events were masked previously in the chain
+	 * handler
+	 */
+	for (i = 0; i < prcm_irq_setup->nr_regs; i++)
+		prcm_irq_write_reg(prcm_irq_setup->saved_mask[i],
+			prcm_irq_setup->mask + i * 4);
+}
+
 /*
  * Initializes the prcm chain handler based on provided parameters
  */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 4/8] ARM: OMAP: prcm: add suspend prepare / finish support
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

PRCM chain handler needs to disable forwarding of interrupts during
suspend, because runtime PM is disabled and most of the drivers
are potentially not able to handle interrupts coming at this time.

This patch masks all the PRCM interrupt events if a PRCM interrupt
occurs during suspend, but does not ack them. Once suspend finish
is called, all the masked events will be re-enabled, which causes
immediate PRCM interrupt and handles the postponed event.

The suspend prepare and complete  callbacks will be called from
pm34xx.c / pm44xx.c files in the following patches.

The functions defined in this patch should eventually be moved to
suspend->prepare and suspend->finish driver hooks, once the PRCM
chain handler will be made as its own driver.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/prcm-common.h |    4 +++
 arch/arm/mach-omap2/prcm.c        |   46 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 3c54e3c..6cb0daf 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -425,6 +425,8 @@ struct omap_prcm_irq_setup {
 	u32 *priority_mask;
 	int base_irq;
 	int irq;
+	bool suspended;
+	bool suspend_save_flag;
 };
 
 #define OMAP_PRCM_IRQ(_name, _offset, _priority) {	\
@@ -437,6 +439,8 @@ extern void omap_prcm_irq_cleanup(void);
 extern int omap_prcm_register_chain_handler(
 	struct omap_prcm_irq_setup *irq_setup);
 extern int omap_prcm_event_to_irq(const char *event);
+extern void omap_prcm_irq_prepare(void);
+extern void omap_prcm_irq_complete(void);
 # endif
 
 #endif
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 948247f..e7c8f3f 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -221,12 +221,28 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	unsigned int virtirq;
 	int nr_irqs = prcm_irq_setup->nr_regs * 32;
+	int i;
+
+	/*
+	 * If we are suspended, mask all interrupts from PRCM level,
+	 * this does not ack them, and they will be pending until
+	 * we re-enable the interrupts, at which point the
+	 * omap_prcm_irq_handler will be executed again
+	 */
+	if (prcm_irq_setup->suspended) {
+		for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
+			prcm_irq_setup->saved_mask[i] =
+				prcm_irq_read_reg(prcm_irq_setup->mask + i * 4);
+			prcm_irq_write_reg(0, prcm_irq_setup->mask + i * 4);
+		}
+		prcm_irq_setup->suspend_save_flag = true;
+	}
 
 	/*
 	 * Loop until all pending irqs are handled, since
 	 * generic_handle_irq() can cause new irqs to come
 	 */
-	while (1) {
+	while (!prcm_irq_setup->suspended) {
 		omap_prm_pending_events(pending);
 
 		/* No bit set, then all IRQs are handled */
@@ -307,6 +323,34 @@ void omap_prcm_irq_cleanup(void)
 	prcm_irq_setup->base_irq = 0;
 }
 
+void omap_prcm_irq_prepare(void)
+{
+	prcm_irq_setup->suspended = true;
+}
+
+void omap_prcm_irq_complete(void)
+{
+	int i;
+
+	prcm_irq_setup->suspended = false;
+
+	/* If we have not saved the masks, do not attempt to restore */
+	if (!prcm_irq_setup->suspend_save_flag)
+		return;
+
+	prcm_irq_setup->suspend_save_flag = false;
+
+	/*
+	 * Re-enable all masked PRCM irq sources, this
+	 * causes the PRCM interrupt to fire immediately
+	 * if the events were masked previously in the chain
+	 * handler
+	 */
+	for (i = 0; i < prcm_irq_setup->nr_regs; i++)
+		prcm_irq_write_reg(prcm_irq_setup->saved_mask[i],
+			prcm_irq_setup->mask + i * 4);
+}
+
 /*
  * Initializes the prcm chain handler based on provided parameters
  */
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 5/8] ARM: OMAP2+: mux: add support for PAD wakeup interrupts
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

OMAP mux now parses active wakeup events from pad registers and
calls corresponding hwmod ISRs once a wakeup is detected. This is
accomplished by registering an interrupt handler for PRCM IO event,
which is raised every time the HW detects wakeups.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/mux.c |   38 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 5f15ab8..0d1962e 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -32,6 +32,8 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 #include <asm/system.h>
 
@@ -39,6 +41,7 @@
 
 #include "control.h"
 #include "mux.h"
+#include "prcm-common.h"
 
 #define OMAP_MUX_BASE_OFFSET		0x30	/* Offset from CTRL_BASE */
 #define OMAP_MUX_BASE_SZ		0x5ca
@@ -381,6 +384,33 @@ bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
 	return ret;
 }
 
+/**
+ * omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
+ *
+ * Checks a single hwmod for every wakeup capable pad to see if there is an
+ * active wakeup event. If this is the case, call the corresponding ISR.
+ */
+static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
+{
+	if (!oh->mux || !oh->mux->enabled)
+		return 0;
+	if (omap_hwmod_mux_get_wake_status(oh->mux))
+		generic_handle_irq(oh->mpu_irqs[0].irq);
+	return 0;
+}
+
+/**
+ * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
+ *
+ * Calls a function for each registered omap_hwmod to check
+ * pad wakeup statuses.
+ */
+static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
+{
+	omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
+	return IRQ_HANDLED;
+}
+
 /* Assumes the calling function takes care of locking */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
 {
@@ -745,6 +775,7 @@ static void __init omap_mux_free_names(struct omap_mux *m)
 static int __init omap_mux_late_init(void)
 {
 	struct omap_mux_partition *partition;
+	int ret;
 
 	list_for_each_entry(partition, &mux_partitions, node) {
 		struct omap_mux_entry *e, *tmp;
@@ -765,6 +796,13 @@ static int __init omap_mux_late_init(void)
 		}
 	}
 
+	ret = request_irq(omap_prcm_event_to_irq("io"),
+		omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
+			"hwmod_io", omap_mux_late_init);
+
+	if (ret)
+		printk(KERN_WARNING "Failed to setup hwmod io irq %d\n", ret);
+
 	omap_mux_dbg_init();
 
 	return 0;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 5/8] ARM: OMAP2+: mux: add support for PAD wakeup interrupts
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

OMAP mux now parses active wakeup events from pad registers and
calls corresponding hwmod ISRs once a wakeup is detected. This is
accomplished by registering an interrupt handler for PRCM IO event,
which is raised every time the HW detects wakeups.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/mux.c |   38 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 5f15ab8..0d1962e 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -32,6 +32,8 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 #include <asm/system.h>
 
@@ -39,6 +41,7 @@
 
 #include "control.h"
 #include "mux.h"
+#include "prcm-common.h"
 
 #define OMAP_MUX_BASE_OFFSET		0x30	/* Offset from CTRL_BASE */
 #define OMAP_MUX_BASE_SZ		0x5ca
@@ -381,6 +384,33 @@ bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
 	return ret;
 }
 
+/**
+ * omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
+ *
+ * Checks a single hwmod for every wakeup capable pad to see if there is an
+ * active wakeup event. If this is the case, call the corresponding ISR.
+ */
+static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
+{
+	if (!oh->mux || !oh->mux->enabled)
+		return 0;
+	if (omap_hwmod_mux_get_wake_status(oh->mux))
+		generic_handle_irq(oh->mpu_irqs[0].irq);
+	return 0;
+}
+
+/**
+ * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
+ *
+ * Calls a function for each registered omap_hwmod to check
+ * pad wakeup statuses.
+ */
+static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
+{
+	omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
+	return IRQ_HANDLED;
+}
+
 /* Assumes the calling function takes care of locking */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
 {
@@ -745,6 +775,7 @@ static void __init omap_mux_free_names(struct omap_mux *m)
 static int __init omap_mux_late_init(void)
 {
 	struct omap_mux_partition *partition;
+	int ret;
 
 	list_for_each_entry(partition, &mux_partitions, node) {
 		struct omap_mux_entry *e, *tmp;
@@ -765,6 +796,13 @@ static int __init omap_mux_late_init(void)
 		}
 	}
 
+	ret = request_irq(omap_prcm_event_to_irq("io"),
+		omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
+			"hwmod_io", omap_mux_late_init);
+
+	if (ret)
+		printk(KERN_WARNING "Failed to setup hwmod io irq %d\n", ret);
+
 	omap_mux_dbg_init();
 
 	return 0;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 6/8] ARM: OMAP3: pm: use prcm chain handler
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

PM interrupt handling is now done through the PRCM chain handler. The
interrupt handling logic is also split in two parts, to serve IO and
WKUP events separately. This allows us to handle IO chain events in a
clean way.

Core event code is also changed in accordance to this, as PRCM
interrupt handling is done by independent handlers, and the core
handler should not clear the IO events anymore.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c       |  111 ++++++++++++++----------------------
 arch/arm/mach-omap2/prm2xxx_3xxx.c |    1 +
 2 files changed, 45 insertions(+), 67 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index efa6649..5fd99e5 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -194,7 +194,7 @@ static void omap3_save_secure_ram_context(void)
  * that any peripheral wake-up events occurring while attempting to
  * clear the PM_WKST_x are detected and cleared.
  */
-static int prcm_clear_mod_irqs(s16 module, u8 regs)
+static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
 {
 	u32 wkst, fclk, iclk, clken;
 	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
@@ -206,6 +206,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 
 	wkst = omap2_prm_read_mod_reg(module, wkst_off);
 	wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
+	wkst &= ~ignore_bits;
 	if (wkst) {
 		iclk = omap2_cm_read_mod_reg(module, iclk_off);
 		fclk = omap2_cm_read_mod_reg(module, fclk_off);
@@ -221,6 +222,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 			omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
 			omap2_prm_write_mod_reg(wkst, module, wkst_off);
 			wkst = omap2_prm_read_mod_reg(module, wkst_off);
+			wkst &= ~ignore_bits;
 			c++;
 		}
 		omap2_cm_write_mod_reg(iclk, module, iclk_off);
@@ -230,76 +232,35 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 	return c;
 }
 
-static int _prcm_int_handle_wakeup(void)
+static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
 {
 	int c;
 
-	c = prcm_clear_mod_irqs(WKUP_MOD, 1);
-	c += prcm_clear_mod_irqs(CORE_MOD, 1);
-	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
-	if (omap_rev() > OMAP3430_REV_ES1_0) {
-		c += prcm_clear_mod_irqs(CORE_MOD, 3);
-		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
-	}
+	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
+		~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK));
 
-	return c;
+	return c ? IRQ_HANDLED : IRQ_NONE;
 }
 
-/*
- * PRCM Interrupt Handler
- *
- * The PRM_IRQSTATUS_MPU register indicates if there are any pending
- * interrupts from the PRCM for the MPU. These bits must be cleared in
- * order to clear the PRCM interrupt. The PRCM interrupt handler is
- * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
- * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
- * register indicates that a wake-up event is pending for the MPU and
- * this bit can only be cleared if the all the wake-up events latched
- * in the various PM_WKST_x registers have been cleared. The interrupt
- * handler is implemented using a do-while loop so that if a wake-up
- * event occurred during the processing of the prcm interrupt handler
- * (setting a bit in the corresponding PM_WKST_x register and thus
- * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
- * this would be handled.
- */
-static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
 {
-	u32 irqenable_mpu, irqstatus_mpu;
-	int c = 0;
-
-	irqenable_mpu = omap2_prm_read_mod_reg(OCP_MOD,
-					 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
-	irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
-					 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-	irqstatus_mpu &= irqenable_mpu;
-
-	do {
-		if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
-				     OMAP3430_IO_ST_MASK)) {
-			c = _prcm_int_handle_wakeup();
-
-			/*
-			 * Is the MPU PRCM interrupt handler racing with the
-			 * IVA2 PRCM interrupt handler ?
-			 */
-			WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
-			     "but no wakeup sources are marked\n");
-		} else {
-			/* XXX we need to expand our PRCM interrupt handler */
-			WARN(1, "prcm: WARNING: PRCM interrupt received, but "
-			     "no code to handle it (%08x)\n", irqstatus_mpu);
-		}
-
-		omap2_prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
-					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-
-		irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
-					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-		irqstatus_mpu &= irqenable_mpu;
+	int c;
 
-	} while (irqstatus_mpu);
+	/*
+	 * Clear all except ST_IO and ST_IO_CHAIN for wkup module,
+	 * these are handled in a separate handler to avoid acking
+	 * IO events before parsing in mux code
+	 */
+	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
+		OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK);
+	c += prcm_clear_mod_irqs(CORE_MOD, 1, 0);
+	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
+	if (omap_rev() > OMAP3430_REV_ES1_0) {
+		c += prcm_clear_mod_irqs(CORE_MOD, 3, 0);
+		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
+	}
 
-	return IRQ_HANDLED;
+	return c ? IRQ_HANDLED : IRQ_NONE;
 }
 
 static void omap34xx_save_context(u32 *save)
@@ -580,6 +541,7 @@ static int omap3_pm_begin(suspend_state_t state)
 	disable_hlt();
 	suspend_state = state;
 	omap_uart_enable_irqs(0);
+	omap_prcm_irq_prepare();
 	return 0;
 }
 
@@ -591,10 +553,16 @@ static void omap3_pm_end(void)
 	return;
 }
 
+static void omap3_pm_finish(void)
+{
+	omap_prcm_irq_complete();
+}
+
 static const struct platform_suspend_ops omap_pm_ops = {
 	.begin		= omap3_pm_begin,
 	.end		= omap3_pm_end,
 	.enter		= omap3_pm_enter,
+	.finish		= omap3_pm_finish,
 	.valid		= suspend_valid_only_mem,
 };
 #endif /* CONFIG_SUSPEND */
@@ -880,12 +848,21 @@ static int __init omap3_pm_init(void)
 	 * supervised mode for powerdomains */
 	prcm_setup_regs();
 
-	ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
-			  (irq_handler_t)prcm_interrupt_handler,
-			  IRQF_DISABLED, "prcm", NULL);
+	ret = request_irq(omap_prcm_event_to_irq("wkup"),
+		_prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL);
+
+	if (ret) {
+		printk(KERN_ERR "Failed to request pm_wkup irq\n");
+		goto err1;
+	}
+
+	/* IO interrupt is shared with mux code */
+	ret = request_irq(omap_prcm_event_to_irq("io"),
+		_prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
+		omap3_pm_init);
+
 	if (ret) {
-		printk(KERN_ERR "request_irq failed to register for 0x%x\n",
-		       INT_34XX_PRCM_MPU_IRQ);
+		printk(KERN_ERR "Failed to request pm_io irq\n");
 		goto err1;
 	}
 
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9f1aad3..0fc72a4 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -233,3 +233,4 @@ static int __init omap3xxx_prcm_init(void)
 		return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
 	return 0;
 }
+subsys_initcall(omap3xxx_prcm_init);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 6/8] ARM: OMAP3: pm: use prcm chain handler
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

PM interrupt handling is now done through the PRCM chain handler. The
interrupt handling logic is also split in two parts, to serve IO and
WKUP events separately. This allows us to handle IO chain events in a
clean way.

Core event code is also changed in accordance to this, as PRCM
interrupt handling is done by independent handlers, and the core
handler should not clear the IO events anymore.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c       |  111 ++++++++++++++----------------------
 arch/arm/mach-omap2/prm2xxx_3xxx.c |    1 +
 2 files changed, 45 insertions(+), 67 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index efa6649..5fd99e5 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -194,7 +194,7 @@ static void omap3_save_secure_ram_context(void)
  * that any peripheral wake-up events occurring while attempting to
  * clear the PM_WKST_x are detected and cleared.
  */
-static int prcm_clear_mod_irqs(s16 module, u8 regs)
+static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
 {
 	u32 wkst, fclk, iclk, clken;
 	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
@@ -206,6 +206,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 
 	wkst = omap2_prm_read_mod_reg(module, wkst_off);
 	wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
+	wkst &= ~ignore_bits;
 	if (wkst) {
 		iclk = omap2_cm_read_mod_reg(module, iclk_off);
 		fclk = omap2_cm_read_mod_reg(module, fclk_off);
@@ -221,6 +222,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 			omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
 			omap2_prm_write_mod_reg(wkst, module, wkst_off);
 			wkst = omap2_prm_read_mod_reg(module, wkst_off);
+			wkst &= ~ignore_bits;
 			c++;
 		}
 		omap2_cm_write_mod_reg(iclk, module, iclk_off);
@@ -230,76 +232,35 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 	return c;
 }
 
-static int _prcm_int_handle_wakeup(void)
+static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
 {
 	int c;
 
-	c = prcm_clear_mod_irqs(WKUP_MOD, 1);
-	c += prcm_clear_mod_irqs(CORE_MOD, 1);
-	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
-	if (omap_rev() > OMAP3430_REV_ES1_0) {
-		c += prcm_clear_mod_irqs(CORE_MOD, 3);
-		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
-	}
+	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
+		~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK));
 
-	return c;
+	return c ? IRQ_HANDLED : IRQ_NONE;
 }
 
-/*
- * PRCM Interrupt Handler
- *
- * The PRM_IRQSTATUS_MPU register indicates if there are any pending
- * interrupts from the PRCM for the MPU. These bits must be cleared in
- * order to clear the PRCM interrupt. The PRCM interrupt handler is
- * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
- * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
- * register indicates that a wake-up event is pending for the MPU and
- * this bit can only be cleared if the all the wake-up events latched
- * in the various PM_WKST_x registers have been cleared. The interrupt
- * handler is implemented using a do-while loop so that if a wake-up
- * event occurred during the processing of the prcm interrupt handler
- * (setting a bit in the corresponding PM_WKST_x register and thus
- * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
- * this would be handled.
- */
-static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
 {
-	u32 irqenable_mpu, irqstatus_mpu;
-	int c = 0;
-
-	irqenable_mpu = omap2_prm_read_mod_reg(OCP_MOD,
-					 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
-	irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
-					 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-	irqstatus_mpu &= irqenable_mpu;
-
-	do {
-		if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
-				     OMAP3430_IO_ST_MASK)) {
-			c = _prcm_int_handle_wakeup();
-
-			/*
-			 * Is the MPU PRCM interrupt handler racing with the
-			 * IVA2 PRCM interrupt handler ?
-			 */
-			WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
-			     "but no wakeup sources are marked\n");
-		} else {
-			/* XXX we need to expand our PRCM interrupt handler */
-			WARN(1, "prcm: WARNING: PRCM interrupt received, but "
-			     "no code to handle it (%08x)\n", irqstatus_mpu);
-		}
-
-		omap2_prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
-					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-
-		irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
-					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-		irqstatus_mpu &= irqenable_mpu;
+	int c;
 
-	} while (irqstatus_mpu);
+	/*
+	 * Clear all except ST_IO and ST_IO_CHAIN for wkup module,
+	 * these are handled in a separate handler to avoid acking
+	 * IO events before parsing in mux code
+	 */
+	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
+		OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK);
+	c += prcm_clear_mod_irqs(CORE_MOD, 1, 0);
+	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
+	if (omap_rev() > OMAP3430_REV_ES1_0) {
+		c += prcm_clear_mod_irqs(CORE_MOD, 3, 0);
+		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
+	}
 
-	return IRQ_HANDLED;
+	return c ? IRQ_HANDLED : IRQ_NONE;
 }
 
 static void omap34xx_save_context(u32 *save)
@@ -580,6 +541,7 @@ static int omap3_pm_begin(suspend_state_t state)
 	disable_hlt();
 	suspend_state = state;
 	omap_uart_enable_irqs(0);
+	omap_prcm_irq_prepare();
 	return 0;
 }
 
@@ -591,10 +553,16 @@ static void omap3_pm_end(void)
 	return;
 }
 
+static void omap3_pm_finish(void)
+{
+	omap_prcm_irq_complete();
+}
+
 static const struct platform_suspend_ops omap_pm_ops = {
 	.begin		= omap3_pm_begin,
 	.end		= omap3_pm_end,
 	.enter		= omap3_pm_enter,
+	.finish		= omap3_pm_finish,
 	.valid		= suspend_valid_only_mem,
 };
 #endif /* CONFIG_SUSPEND */
@@ -880,12 +848,21 @@ static int __init omap3_pm_init(void)
 	 * supervised mode for powerdomains */
 	prcm_setup_regs();
 
-	ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
-			  (irq_handler_t)prcm_interrupt_handler,
-			  IRQF_DISABLED, "prcm", NULL);
+	ret = request_irq(omap_prcm_event_to_irq("wkup"),
+		_prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL);
+
+	if (ret) {
+		printk(KERN_ERR "Failed to request pm_wkup irq\n");
+		goto err1;
+	}
+
+	/* IO interrupt is shared with mux code */
+	ret = request_irq(omap_prcm_event_to_irq("io"),
+		_prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
+		omap3_pm_init);
+
 	if (ret) {
-		printk(KERN_ERR "request_irq failed to register for 0x%x\n",
-		       INT_34XX_PRCM_MPU_IRQ);
+		printk(KERN_ERR "Failed to request pm_io irq\n");
 		goto err1;
 	}
 
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9f1aad3..0fc72a4 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -233,3 +233,4 @@ static int __init omap3xxx_prcm_init(void)
 		return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
 	return 0;
 }
+subsys_initcall(omap3xxx_prcm_init);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 7/8] ARM: OMAP3: pm: do not enable PRCM MPU interrupts manually
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

This is handled automatically by the PRCM chain interrupt mechanism now.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 5fd99e5..d5ce8d2 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -668,10 +668,6 @@ static void __init prcm_setup_regs(void)
 			  OMAP3430_GRPSEL_GPT1_MASK |
 			  OMAP3430_GRPSEL_GPT12_MASK,
 			  WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
-	/* For some reason IO doesn't generate wakeup event even if
-	 * it is selected to mpu wakeup goup */
-	omap2_prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK,
-			  OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 
 	/* Enable PM_WKEN to support DSS LPR */
 	omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 7/8] ARM: OMAP3: pm: do not enable PRCM MPU interrupts manually
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

This is handled automatically by the PRCM chain interrupt mechanism now.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 5fd99e5..d5ce8d2 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -668,10 +668,6 @@ static void __init prcm_setup_regs(void)
 			  OMAP3430_GRPSEL_GPT1_MASK |
 			  OMAP3430_GRPSEL_GPT12_MASK,
 			  WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
-	/* For some reason IO doesn't generate wakeup event even if
-	 * it is selected to mpu wakeup goup */
-	omap2_prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK,
-			  OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 
 	/* Enable PM_WKEN to support DSS LPR */
 	omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 8/8] ARM: OMAP: mux: add support for selecting mpu_irq for each wakeup pad
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-12 18:15   ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

By default all registered pads will trigger mpu_irqs[0]. Now there is
an API for selecting used mpu_irq on pad basis, which can be used to
trigger different irq handlers for different pads in the same hwmod.
Each pad that requires its interrupt to be re-routed this way must
have a separate call to omap_hwmod_pad_route_irq(hwmod, pad, irq).

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/mux.c                    |   67 ++++++++++++++++++++++----
 arch/arm/mach-omap2/omap_hwmod.c             |    7 ---
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    4 ++
 3 files changed, 61 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 0d1962e..2da3f3d 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -354,19 +354,53 @@ err1:
 	return NULL;
 }
 
+int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx,
+		int irq_idx)
+{
+	int nr_irqs;
+
+	if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
+	    pad_idx >= oh->mux->nr_pads_dynamic)
+		return -EINVAL;
+
+	/* Check the number of available mpu_irqs */
+	for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
+		;
+
+	if (irq_idx >= nr_irqs)
+		return -EINVAL;
+
+	if (!oh->mux->irqs) {
+		oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
+			GFP_KERNEL);
+		if (!oh->mux->irqs)
+			return -ENOMEM;
+	}
+	oh->mux->irqs[pad_idx] = irq_idx;
+
+	return 0;
+}
+
 /**
- * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
+ * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
  * @hmux:		Pads for a hwmod
+ * @mpu_irqs:		MPU irq array for a hwmod
  *
- * Gets the wakeup status of given pad from omap-hwmod.
- * Returns true if wakeup event is set for pad else false
- * if wakeup is not occured or pads are not avialable.
+ * Scans the wakeup status of pads for a single hwmod.
+ * If an irq array is defined for this mux, the parser
+ * will call the registered ISRs for corresponding pads,
+ * otherwise the parser will stop at the first wakeup
+ * active pad and return.
+ * Returns true if there is a pending and non-served
+ * wakeup event for the mux, otherwise false.
  */
-bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
+static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
+		struct omap_hwmod_irq_info *mpu_irqs)
 {
 	int i;
 	unsigned int val;
-	u8 ret = false;
+	u32 handled_irqs = 0;
+	int irq;
 
 	for (i = 0; i < hmux->nr_pads; i++) {
 		struct omap_device_pad *pad = &hmux->pads[i];
@@ -375,13 +409,26 @@ bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
 			val = omap_mux_read(pad->partition,
 					pad->mux->reg_offset);
 			if (val & OMAP_WAKEUP_EVENT) {
-				ret = true;
-				break;
+				if (hmux->irqs) {
+					irq = hmux->irqs[i];
+					/*
+					 * make sure we only handle each
+					 * irq once
+					 */
+					if (handled_irqs & 1 << irq)
+						continue;
+
+					handled_irqs |= 1 << irq;
+
+					generic_handle_irq(mpu_irqs[irq].irq);
+				} else {
+					return true;
+				}
 			}
 		}
 	}
 
-	return ret;
+	return false;
 }
 
 /**
@@ -394,7 +441,7 @@ static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
 {
 	if (!oh->mux || !oh->mux->enabled)
 		return 0;
-	if (omap_hwmod_mux_get_wake_status(oh->mux))
+	if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
 		generic_handle_irq(oh->mpu_irqs[0].irq);
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index d7f4623..8d37d83 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2721,10 +2721,3 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
 
 	return 0;
 }
-
-int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
-{
-	if (oh && oh->mux)
-		return omap_hwmod_mux_get_wake_status(oh->mux);
-	return -EINVAL;
-}
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1b81dfb..a5f0a5f 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -97,6 +97,7 @@ struct omap_hwmod_mux_info {
 	struct omap_device_pad		*pads;
 	int				nr_pads_dynamic;
 	struct omap_device_pad		**pads_dynamic;
+	int				*irqs;
 	bool				enabled;
 };
 
@@ -605,6 +606,9 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
 
 int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh);
+
+int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
+
 /*
  * Chip variant-specific hwmod init routines - XXX should be converted
  * to use initcalls once the initial boot ordering is straightened out
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 8/8] ARM: OMAP: mux: add support for selecting mpu_irq for each wakeup pad
@ 2011-12-12 18:15   ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-12 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

By default all registered pads will trigger mpu_irqs[0]. Now there is
an API for selecting used mpu_irq on pad basis, which can be used to
trigger different irq handlers for different pads in the same hwmod.
Each pad that requires its interrupt to be re-routed this way must
have a separate call to omap_hwmod_pad_route_irq(hwmod, pad, irq).

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/mux.c                    |   67 ++++++++++++++++++++++----
 arch/arm/mach-omap2/omap_hwmod.c             |    7 ---
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    4 ++
 3 files changed, 61 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 0d1962e..2da3f3d 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -354,19 +354,53 @@ err1:
 	return NULL;
 }
 
+int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx,
+		int irq_idx)
+{
+	int nr_irqs;
+
+	if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
+	    pad_idx >= oh->mux->nr_pads_dynamic)
+		return -EINVAL;
+
+	/* Check the number of available mpu_irqs */
+	for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
+		;
+
+	if (irq_idx >= nr_irqs)
+		return -EINVAL;
+
+	if (!oh->mux->irqs) {
+		oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
+			GFP_KERNEL);
+		if (!oh->mux->irqs)
+			return -ENOMEM;
+	}
+	oh->mux->irqs[pad_idx] = irq_idx;
+
+	return 0;
+}
+
 /**
- * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
+ * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
  * @hmux:		Pads for a hwmod
+ * @mpu_irqs:		MPU irq array for a hwmod
  *
- * Gets the wakeup status of given pad from omap-hwmod.
- * Returns true if wakeup event is set for pad else false
- * if wakeup is not occured or pads are not avialable.
+ * Scans the wakeup status of pads for a single hwmod.
+ * If an irq array is defined for this mux, the parser
+ * will call the registered ISRs for corresponding pads,
+ * otherwise the parser will stop at the first wakeup
+ * active pad and return.
+ * Returns true if there is a pending and non-served
+ * wakeup event for the mux, otherwise false.
  */
-bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
+static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
+		struct omap_hwmod_irq_info *mpu_irqs)
 {
 	int i;
 	unsigned int val;
-	u8 ret = false;
+	u32 handled_irqs = 0;
+	int irq;
 
 	for (i = 0; i < hmux->nr_pads; i++) {
 		struct omap_device_pad *pad = &hmux->pads[i];
@@ -375,13 +409,26 @@ bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
 			val = omap_mux_read(pad->partition,
 					pad->mux->reg_offset);
 			if (val & OMAP_WAKEUP_EVENT) {
-				ret = true;
-				break;
+				if (hmux->irqs) {
+					irq = hmux->irqs[i];
+					/*
+					 * make sure we only handle each
+					 * irq once
+					 */
+					if (handled_irqs & 1 << irq)
+						continue;
+
+					handled_irqs |= 1 << irq;
+
+					generic_handle_irq(mpu_irqs[irq].irq);
+				} else {
+					return true;
+				}
 			}
 		}
 	}
 
-	return ret;
+	return false;
 }
 
 /**
@@ -394,7 +441,7 @@ static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
 {
 	if (!oh->mux || !oh->mux->enabled)
 		return 0;
-	if (omap_hwmod_mux_get_wake_status(oh->mux))
+	if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
 		generic_handle_irq(oh->mpu_irqs[0].irq);
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index d7f4623..8d37d83 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2721,10 +2721,3 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
 
 	return 0;
 }
-
-int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
-{
-	if (oh && oh->mux)
-		return omap_hwmod_mux_get_wake_status(oh->mux);
-	return -EINVAL;
-}
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1b81dfb..a5f0a5f 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -97,6 +97,7 @@ struct omap_hwmod_mux_info {
 	struct omap_device_pad		*pads;
 	int				nr_pads_dynamic;
 	struct omap_device_pad		**pads_dynamic;
+	int				*irqs;
 	bool				enabled;
 };
 
@@ -605,6 +606,9 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
 
 int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh);
+
+int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
+
 /*
  * Chip variant-specific hwmod init routines - XXX should be converted
  * to use initcalls once the initial boot ordering is straightened out
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 5/8] ARM: OMAP2+: mux: add support for PAD wakeup interrupts
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-13  0:24     ` Tony Lindgren
  -1 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:24 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> OMAP mux now parses active wakeup events from pad registers and
> calls corresponding hwmod ISRs once a wakeup is detected. This is
> accomplished by registering an interrupt handler for PRCM IO event,
> which is raised every time the HW detects wakeups.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

This will need to be updated once we are using the pinctrl
framework, for now this looks good to me:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 5/8] ARM: OMAP2+: mux: add support for PAD wakeup interrupts
@ 2011-12-13  0:24     ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:24 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> OMAP mux now parses active wakeup events from pad registers and
> calls corresponding hwmod ISRs once a wakeup is detected. This is
> accomplished by registering an interrupt handler for PRCM IO event,
> which is raised every time the HW detects wakeups.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

This will need to be updated once we are using the pinctrl
framework, for now this looks good to me:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 8/8] ARM: OMAP: mux: add support for selecting mpu_irq for each wakeup pad
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-13  0:25     ` Tony Lindgren
  -1 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:25 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> By default all registered pads will trigger mpu_irqs[0]. Now there is
> an API for selecting used mpu_irq on pad basis, which can be used to
> trigger different irq handlers for different pads in the same hwmod.
> Each pad that requires its interrupt to be re-routed this way must
> have a separate call to omap_hwmod_pad_route_irq(hwmod, pad, irq).
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 8/8] ARM: OMAP: mux: add support for selecting mpu_irq for each wakeup pad
@ 2011-12-13  0:25     ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:25 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> By default all registered pads will trigger mpu_irqs[0]. Now there is
> an API for selecting used mpu_irq on pad basis, which can be used to
> trigger different irq handlers for different pads in the same hwmod.
> Each pad that requires its interrupt to be re-routed this way must
> have a separate call to omap_hwmod_pad_route_irq(hwmod, pad, irq).
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 3/8] ARM: OMAP: prm: add support for chain interrupt handler
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-13  0:27     ` Tony Lindgren
  -1 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:27 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-omap, linux-arm-kernel, Paul Walmsley, Kevin Hilman,
	Avinash.H.M, Cousson, Benoit, Govindraj.R

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> Introduce a chained interrupt handler mechanism for the PRCM
> interrupt, so that individual PRCM event can cleanly be handled by
> handlers in separate drivers. We do this by introducing PRCM event
> names, which are then matched to the particular PRCM interrupt bit
> depending on the specific OMAP SoC being used.
> 
> PRCM interrupts have two priority levels, high or normal. High priority
> is needed for IO event handling, so that we can be sure that IO events
> are processed before other events. This reduces latency for IO event
> customers and also prevents incorrect ack sequence on OMAP3.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@ti.com>
> Cc: Avinash.H.M <avinashhm@ti.com>
> Cc: Cousson, Benoit <b-cousson@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Govindraj.R <govindraj.raja@ti.com>

Assuming Paul will queue these:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 3/8] ARM: OMAP: prm: add support for chain interrupt handler
@ 2011-12-13  0:27     ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:27 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> Introduce a chained interrupt handler mechanism for the PRCM
> interrupt, so that individual PRCM event can cleanly be handled by
> handlers in separate drivers. We do this by introducing PRCM event
> names, which are then matched to the particular PRCM interrupt bit
> depending on the specific OMAP SoC being used.
> 
> PRCM interrupts have two priority levels, high or normal. High priority
> is needed for IO event handling, so that we can be sure that IO events
> are processed before other events. This reduces latency for IO event
> customers and also prevents incorrect ack sequence on OMAP3.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@ti.com>
> Cc: Avinash.H.M <avinashhm@ti.com>
> Cc: Cousson, Benoit <b-cousson@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Govindraj.R <govindraj.raja@ti.com>

Assuming Paul will queue these:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-13  0:28     ` Tony Lindgren
  -1 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:28 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-arm-kernel, R, Govindraj

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to determine IO-PAD wakeup event status for a given
> hwmod dynamic_mux pad.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-13  0:28     ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13  0:28 UTC (permalink / raw)
  To: linux-arm-kernel

* Tero Kristo <t-kristo@ti.com> [111212 09:44]:
> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to determine IO-PAD wakeup event status for a given
> hwmod dynamic_mux pad.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 0/8] OMAP3+: PRCM chain handler
  2011-12-12 18:15 ` Tero Kristo
@ 2011-12-13  0:33   ` Kevin Hilman
  -1 siblings, 0 replies; 54+ messages in thread
From: Kevin Hilman @ 2011-12-13  0:33 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-arm-kernel

Tero Kristo <t-kristo@ti.com> writes:


> PRCM chain handler is adding a support to the omap3+ kernel that
> allows different drivers to use PRCM interrupt events for their
> own purposes, typically this means IO wakeups. This work was
> attempted to integrate as its own driver at some point of
> the evolution of this set, however this was now postponed as
> the lacking support is basically blocking a few drivers.
>
> This is the version 11 of this set, now posted to linux-arm-kernel also
> as cc. Contains just a couple of minor changes compared to previous
> version proposed by Kevin Hilman.

Thanks Tero for the quick update.  

All of this series can go through Paul, so from my side

Reviewed-by: Kevin Hilman <khilman@ti.com>
Tested-by: Kevin Hilman <khilman@ti.com>

Kevin

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 0/8] OMAP3+: PRCM chain handler
@ 2011-12-13  0:33   ` Kevin Hilman
  0 siblings, 0 replies; 54+ messages in thread
From: Kevin Hilman @ 2011-12-13  0:33 UTC (permalink / raw)
  To: linux-arm-kernel

Tero Kristo <t-kristo@ti.com> writes:


> PRCM chain handler is adding a support to the omap3+ kernel that
> allows different drivers to use PRCM interrupt events for their
> own purposes, typically this means IO wakeups. This work was
> attempted to integrate as its own driver at some point of
> the evolution of this set, however this was now postponed as
> the lacking support is basically blocking a few drivers.
>
> This is the version 11 of this set, now posted to linux-arm-kernel also
> as cc. Contains just a couple of minor changes compared to previous
> version proposed by Kevin Hilman.

Thanks Tero for the quick update.  

All of this series can go through Paul, so from my side

Reviewed-by: Kevin Hilman <khilman@ti.com>
Tested-by: Kevin Hilman <khilman@ti.com>

Kevin

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-13 20:51     ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 20:51 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-arm-kernel, R, Govindraj

Hi Tero

On Mon, 12 Dec 2011, Tero Kristo wrote:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to enable IO pad wakeup capability based on mux dynamic pad and
> wake_up enable flag available from hwmod_mux initialization.
> 
> Use the wakeup_enable flag and enable wakeup capability
> for the given pads. Wakeup capability will be enabled/disabled
> during hwmod idle transition based on whether wakeup_flag is
> set or cleared.
> 
> Map the enable/disable pad wakeup API's to hwmod_wakeup_enable/disable.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

Since you're in the submitter chain for these patches, I'll need your 
Signed-off-by on this patch and the next one.  Okay to add it?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
@ 2011-12-13 20:51     ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero

On Mon, 12 Dec 2011, Tero Kristo wrote:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to enable IO pad wakeup capability based on mux dynamic pad and
> wake_up enable flag available from hwmod_mux initialization.
> 
> Use the wakeup_enable flag and enable wakeup capability
> for the given pads. Wakeup capability will be enabled/disabled
> during hwmod idle transition based on whether wakeup_flag is
> set or cleared.
> 
> Map the enable/disable pad wakeup API's to hwmod_wakeup_enable/disable.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

Since you're in the submitter chain for these patches, I'll need your 
Signed-off-by on this patch and the next one.  Okay to add it?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-13 21:04     ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 21:04 UTC (permalink / raw)
  To: R, Govindraj, Tero Kristo; +Cc: linux-omap, linux-arm-kernel

Hi

On Mon, 12 Dec 2011, Tero Kristo wrote:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to enable IO pad wakeup capability based on mux dynamic pad and
> wake_up enable flag available from hwmod_mux initialization.
> 
> Use the wakeup_enable flag and enable wakeup capability
> for the given pads. Wakeup capability will be enabled/disabled
> during hwmod idle transition based on whether wakeup_flag is
> set or cleared.
> 
> Map the enable/disable pad wakeup API's to hwmod_wakeup_enable/disable.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

A few changes have been made to this patch:

- The documentation has been improved

- omap_hwmod_{enable,disable}_ioring_wakeup() have been removed, since 
  they are not called outside the omap_hwmod code and were missing 
  function prototypes in omap_hwmod.h

- The omap_hwmod_set_ioring_wakeup() function has been modified to
  not return anything, and indentation depth has been reduced

I still don't think this patch is 100% correct.  For example, if 
omap_hwmod_enable_wakeup() or omap_hwmod_disable_wakeup() is called on an 
idle hwmod, shouldn't the caller expect the SCM PADCONF registers to be 
updated immediately?  The current code merely changes the dynamic mux 
data.  If there is some rationale for not updating the hardware registers 
at this point, I'd like to know what it is.

Modified patch is below; please let me know if you have any comments.
I may modify it again to synchronize the hardware with the in-memory 
settings immediately.


- Paul

From: Govindraj R <govindraj.raja@ti.com>
Date: Tue, 13 Dec 2011 13:50:23 -0700
Subject: [PATCH] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup

Add API to enable IO pad wakeup capability based on mux dynamic pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability
for the given pads. Wakeup capability will be enabled/disabled
during hwmod idle transition based on whether wakeup_flag is
set or cleared.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
XXX Tero's sign-off?
[paul@pwsan.com: rearranged code to limit indentation, cleaned up
 documentation, removed unused non-static functions]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   39 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 207a2ff..ec19841 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -381,6 +381,43 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 }
 
 /**
+ * _set_ioring_wakeup - enable/disable IO pad wakeup flag for dynamic muxing
+ * @oh: struct omap_hwmod *
+ * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
+ *
+ * Set or clear the I/O pad wakeup flag in the dynamic mux entries for
+ * the hwmod @oh.  This function does not change anything in the
+ * hardware.  Rather, the @oh->mux->pads_dynamic array is changed, and
+ * these settings are later written to the SCM PADCTRL registers when
+ * the hwmod is enabled or idled.  No return value.
+ *
+ * XXX Shouldn't the dynamic pad changes affect hwmod shutdown as
+ * well?
+ * XXX Shouldn't this function update the hardware SCM PADCONF registers if
+ * anything has changed?
+ */
+static void _set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	struct omap_device_pad *pad;
+	int j;
+
+	if (!oh->mux || !oh->mux->enabled)
+		return;
+
+	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+		pad = oh->mux->pads_dynamic[j];
+
+		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
+			continue;
+
+		if (set_wake)
+			pad->idle |= OMAP_WAKEUP_EN;
+		else
+			pad->idle &= ~OMAP_WAKEUP_EN;
+	}
+}
+
+/**
  * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
  * @oh: struct omap_hwmod *
  *
@@ -2416,6 +2453,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_enable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_ioring_wakeup(oh, true);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
@@ -2446,6 +2484,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_disable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_ioring_wakeup(oh, false);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
@ 2011-12-13 21:04     ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 21:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Mon, 12 Dec 2011, Tero Kristo wrote:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to enable IO pad wakeup capability based on mux dynamic pad and
> wake_up enable flag available from hwmod_mux initialization.
> 
> Use the wakeup_enable flag and enable wakeup capability
> for the given pads. Wakeup capability will be enabled/disabled
> during hwmod idle transition based on whether wakeup_flag is
> set or cleared.
> 
> Map the enable/disable pad wakeup API's to hwmod_wakeup_enable/disable.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

A few changes have been made to this patch:

- The documentation has been improved

- omap_hwmod_{enable,disable}_ioring_wakeup() have been removed, since 
  they are not called outside the omap_hwmod code and were missing 
  function prototypes in omap_hwmod.h

- The omap_hwmod_set_ioring_wakeup() function has been modified to
  not return anything, and indentation depth has been reduced

I still don't think this patch is 100% correct.  For example, if 
omap_hwmod_enable_wakeup() or omap_hwmod_disable_wakeup() is called on an 
idle hwmod, shouldn't the caller expect the SCM PADCONF registers to be 
updated immediately?  The current code merely changes the dynamic mux 
data.  If there is some rationale for not updating the hardware registers 
at this point, I'd like to know what it is.

Modified patch is below; please let me know if you have any comments.
I may modify it again to synchronize the hardware with the in-memory 
settings immediately.


- Paul

From: Govindraj R <govindraj.raja@ti.com>
Date: Tue, 13 Dec 2011 13:50:23 -0700
Subject: [PATCH] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup

Add API to enable IO pad wakeup capability based on mux dynamic pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability
for the given pads. Wakeup capability will be enabled/disabled
during hwmod idle transition based on whether wakeup_flag is
set or cleared.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
XXX Tero's sign-off?
[paul at pwsan.com: rearranged code to limit indentation, cleaned up
 documentation, removed unused non-static functions]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   39 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 207a2ff..ec19841 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -381,6 +381,43 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 }
 
 /**
+ * _set_ioring_wakeup - enable/disable IO pad wakeup flag for dynamic muxing
+ * @oh: struct omap_hwmod *
+ * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
+ *
+ * Set or clear the I/O pad wakeup flag in the dynamic mux entries for
+ * the hwmod @oh.  This function does not change anything in the
+ * hardware.  Rather, the @oh->mux->pads_dynamic array is changed, and
+ * these settings are later written to the SCM PADCTRL registers when
+ * the hwmod is enabled or idled.  No return value.
+ *
+ * XXX Shouldn't the dynamic pad changes affect hwmod shutdown as
+ * well?
+ * XXX Shouldn't this function update the hardware SCM PADCONF registers if
+ * anything has changed?
+ */
+static void _set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	struct omap_device_pad *pad;
+	int j;
+
+	if (!oh->mux || !oh->mux->enabled)
+		return;
+
+	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+		pad = oh->mux->pads_dynamic[j];
+
+		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
+			continue;
+
+		if (set_wake)
+			pad->idle |= OMAP_WAKEUP_EN;
+		else
+			pad->idle &= ~OMAP_WAKEUP_EN;
+	}
+}
+
+/**
  * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
  * @oh: struct omap_hwmod *
  *
@@ -2416,6 +2453,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_enable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_ioring_wakeup(oh, true);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
@@ -2446,6 +2484,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_disable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_ioring_wakeup(oh, false);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-12-13 21:04     ` Paul Walmsley
@ 2011-12-13 21:33       ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 21:33 UTC (permalink / raw)
  To: R, Govindraj, Tero Kristo; +Cc: linux-omap, linux-arm-kernel

Hi Govindraj, Tero,

another question about this patch:

On Tue, 13 Dec 2011, Paul Walmsley wrote:

> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 207a2ff..ec19841 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -381,6 +381,43 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
>  }
>  
>  /**
> + * _set_ioring_wakeup - enable/disable IO pad wakeup flag for dynamic muxing
> + * @oh: struct omap_hwmod *
> + * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
> + *
> + * Set or clear the I/O pad wakeup flag in the dynamic mux entries for
> + * the hwmod @oh.  This function does not change anything in the
> + * hardware.  Rather, the @oh->mux->pads_dynamic array is changed, and
> + * these settings are later written to the SCM PADCTRL registers when
> + * the hwmod is enabled or idled.  No return value.
> + *
> + * XXX Shouldn't the dynamic pad changes affect hwmod shutdown as
> + * well?
> + * XXX Shouldn't this function update the hardware SCM PADCONF registers if
> + * anything has changed?
> + */
> +static void _set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
> +{
> +	struct omap_device_pad *pad;
> +	int j;
> +
> +	if (!oh->mux || !oh->mux->enabled)
> +		return;
> +
> +	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
> +		pad = oh->mux->pads_dynamic[j];
> +
> +		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
> +			continue;
> +
> +		if (set_wake)
> +			pad->idle |= OMAP_WAKEUP_EN;
> +		else
> +			pad->idle &= ~OMAP_WAKEUP_EN;
> +	}
> +}

It appears that this loop only affects dynamic mux entries.  Should it 
also affect static mux entries?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
@ 2011-12-13 21:33       ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 21:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Govindraj, Tero,

another question about this patch:

On Tue, 13 Dec 2011, Paul Walmsley wrote:

> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 207a2ff..ec19841 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -381,6 +381,43 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
>  }
>  
>  /**
> + * _set_ioring_wakeup - enable/disable IO pad wakeup flag for dynamic muxing
> + * @oh: struct omap_hwmod *
> + * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
> + *
> + * Set or clear the I/O pad wakeup flag in the dynamic mux entries for
> + * the hwmod @oh.  This function does not change anything in the
> + * hardware.  Rather, the @oh->mux->pads_dynamic array is changed, and
> + * these settings are later written to the SCM PADCTRL registers when
> + * the hwmod is enabled or idled.  No return value.
> + *
> + * XXX Shouldn't the dynamic pad changes affect hwmod shutdown as
> + * well?
> + * XXX Shouldn't this function update the hardware SCM PADCONF registers if
> + * anything has changed?
> + */
> +static void _set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
> +{
> +	struct omap_device_pad *pad;
> +	int j;
> +
> +	if (!oh->mux || !oh->mux->enabled)
> +		return;
> +
> +	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
> +		pad = oh->mux->pads_dynamic[j];
> +
> +		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
> +			continue;
> +
> +		if (set_wake)
> +			pad->idle |= OMAP_WAKEUP_EN;
> +		else
> +			pad->idle &= ~OMAP_WAKEUP_EN;
> +	}
> +}

It appears that this loop only affects dynamic mux entries.  Should it 
also affect static mux entries?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-13 22:16     ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 22:16 UTC (permalink / raw)
  To: R, Govindraj, Tero Kristo; +Cc: linux-omap, linux-arm-kernel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 773 bytes --]

Hi

a question

On Mon, 12 Dec 2011, Tero Kristo wrote:

So the patch description says:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to determine IO-PAD wakeup event status for a given
> hwmod dynamic_mux pad.

But the code does:

> +	for (i = 0; i < hmux->nr_pads; i++) {
> +		struct omap_device_pad *pad = &hmux->pads[i];

which is going to check all of the pads, not just the dynamic ones.

So it seems to me that we need to decide whether this code should be 
testing all the pads, or just the dynamically remuxed ones.  The same 
thing should be decided for the code in patch 1.

Naïvely it seems to me that we want to test all of the pads in both 
patches 1 and 2, not just the dynamically remuxable ones.  Comments?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-13 22:16     ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 22:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

a question

On Mon, 12 Dec 2011, Tero Kristo wrote:

So the patch description says:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to determine IO-PAD wakeup event status for a given
> hwmod dynamic_mux pad.

But the code does:

> +	for (i = 0; i < hmux->nr_pads; i++) {
> +		struct omap_device_pad *pad = &hmux->pads[i];

which is going to check all of the pads, not just the dynamic ones.

So it seems to me that we need to decide whether this code should be 
testing all the pads, or just the dynamically remuxed ones.  The same 
thing should be decided for the code in patch 1.

Na?vely it seems to me that we want to test all of the pads in both 
patches 1 and 2, not just the dynamically remuxable ones.  Comments?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-13 22:16     ` Paul Walmsley
@ 2011-12-13 22:28       ` Tony Lindgren
  -1 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13 22:28 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: R, Govindraj, Tero Kristo, linux-omap, linux-arm-kernel

* Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> Hi
> 
> a question
> 
> On Mon, 12 Dec 2011, Tero Kristo wrote:
> 
> So the patch description says:
> 
> > From: R, Govindraj <govindraj.raja@ti.com>
> > 
> > Add API to determine IO-PAD wakeup event status for a given
> > hwmod dynamic_mux pad.
> 
> But the code does:
> 
> > +	for (i = 0; i < hmux->nr_pads; i++) {
> > +		struct omap_device_pad *pad = &hmux->pads[i];
> 
> which is going to check all of the pads, not just the dynamic ones.
> 
> So it seems to me that we need to decide whether this code should be 
> testing all the pads, or just the dynamically remuxed ones.  The same 
> thing should be decided for the code in patch 1.
> 
> Naïvely it seems to me that we want to test all of the pads in both 
> patches 1 and 2, not just the dynamically remuxable ones.  Comments?

You're right, it should be only the dynamic ones.

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-13 22:28       ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13 22:28 UTC (permalink / raw)
  To: linux-arm-kernel

* Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> Hi
> 
> a question
> 
> On Mon, 12 Dec 2011, Tero Kristo wrote:
> 
> So the patch description says:
> 
> > From: R, Govindraj <govindraj.raja@ti.com>
> > 
> > Add API to determine IO-PAD wakeup event status for a given
> > hwmod dynamic_mux pad.
> 
> But the code does:
> 
> > +	for (i = 0; i < hmux->nr_pads; i++) {
> > +		struct omap_device_pad *pad = &hmux->pads[i];
> 
> which is going to check all of the pads, not just the dynamic ones.
> 
> So it seems to me that we need to decide whether this code should be 
> testing all the pads, or just the dynamically remuxed ones.  The same 
> thing should be decided for the code in patch 1.
> 
> Na?vely it seems to me that we want to test all of the pads in both 
> patches 1 and 2, not just the dynamically remuxable ones.  Comments?

You're right, it should be only the dynamic ones.

Tony

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-13 22:28       ` Tony Lindgren
@ 2011-12-13 22:38         ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 22:38 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: R, Govindraj, Tero Kristo, linux-omap, linux-arm-kernel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1220 bytes --]

On Tue, 13 Dec 2011, Tony Lindgren wrote:

> * Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> > 
> > On Mon, 12 Dec 2011, Tero Kristo wrote:
> > 
> > So the patch description says:
> > 
> > > From: R, Govindraj <govindraj.raja@ti.com>
> > > 
> > > Add API to determine IO-PAD wakeup event status for a given
> > > hwmod dynamic_mux pad.
> > 
> > But the code does:
> > 
> > > +	for (i = 0; i < hmux->nr_pads; i++) {
> > > +		struct omap_device_pad *pad = &hmux->pads[i];
> > 
> > which is going to check all of the pads, not just the dynamic ones.
> > 
> > So it seems to me that we need to decide whether this code should be 
> > testing all the pads, or just the dynamically remuxed ones.  The same 
> > thing should be decided for the code in patch 1.
> > 
> > Naïvely it seems to me that we want to test all of the pads in both 
> > patches 1 and 2, not just the dynamically remuxable ones.  Comments?
> 
> You're right, it should be only the dynamic ones.

Hmm, looks to me like it should check all of them?  Can't a pad be marked 
with OMAP_DEVICE_PAD_WAKEUP, but not be marked with OMAP_DEVICE_PAD_REMUX?  
In that case it would not end up on the dynamic list, right?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-13 22:38         ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-13 22:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 13 Dec 2011, Tony Lindgren wrote:

> * Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> > 
> > On Mon, 12 Dec 2011, Tero Kristo wrote:
> > 
> > So the patch description says:
> > 
> > > From: R, Govindraj <govindraj.raja@ti.com>
> > > 
> > > Add API to determine IO-PAD wakeup event status for a given
> > > hwmod dynamic_mux pad.
> > 
> > But the code does:
> > 
> > > +	for (i = 0; i < hmux->nr_pads; i++) {
> > > +		struct omap_device_pad *pad = &hmux->pads[i];
> > 
> > which is going to check all of the pads, not just the dynamic ones.
> > 
> > So it seems to me that we need to decide whether this code should be 
> > testing all the pads, or just the dynamically remuxed ones.  The same 
> > thing should be decided for the code in patch 1.
> > 
> > Na?vely it seems to me that we want to test all of the pads in both 
> > patches 1 and 2, not just the dynamically remuxable ones.  Comments?
> 
> You're right, it should be only the dynamic ones.

Hmm, looks to me like it should check all of them?  Can't a pad be marked 
with OMAP_DEVICE_PAD_WAKEUP, but not be marked with OMAP_DEVICE_PAD_REMUX?  
In that case it would not end up on the dynamic list, right?


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-13 22:38         ` Paul Walmsley
@ 2011-12-13 22:48           ` Tony Lindgren
  -1 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13 22:48 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: R, Govindraj, Tero Kristo, linux-omap, linux-arm-kernel

* Paul Walmsley <paul@pwsan.com> [111213 14:06]:
> On Tue, 13 Dec 2011, Tony Lindgren wrote:
> 
> > * Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> > > 
> > > On Mon, 12 Dec 2011, Tero Kristo wrote:
> > > 
> > > So the patch description says:
> > > 
> > > > From: R, Govindraj <govindraj.raja@ti.com>
> > > > 
> > > > Add API to determine IO-PAD wakeup event status for a given
> > > > hwmod dynamic_mux pad.
> > > 
> > > But the code does:
> > > 
> > > > +	for (i = 0; i < hmux->nr_pads; i++) {
> > > > +		struct omap_device_pad *pad = &hmux->pads[i];
> > > 
> > > which is going to check all of the pads, not just the dynamic ones.
> > > 
> > > So it seems to me that we need to decide whether this code should be 
> > > testing all the pads, or just the dynamically remuxed ones.  The same 
> > > thing should be decided for the code in patch 1.
> > > 
> > > Naïvely it seems to me that we want to test all of the pads in both 
> > > patches 1 and 2, not just the dynamically remuxable ones.  Comments?
> > 
> > You're right, it should be only the dynamic ones.
> 
> Hmm, looks to me like it should check all of them?  Can't a pad be marked 
> with OMAP_DEVICE_PAD_WAKEUP, but not be marked with OMAP_DEVICE_PAD_REMUX?  
> In that case it would not end up on the dynamic list, right?

Hmm yes that's even more true :) Maybe the right approach would be to
copy the OMAP_DEVICE_PAD_WAKEUP pins also to the dynamic list to
avoid going through all of them.

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-13 22:48           ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2011-12-13 22:48 UTC (permalink / raw)
  To: linux-arm-kernel

* Paul Walmsley <paul@pwsan.com> [111213 14:06]:
> On Tue, 13 Dec 2011, Tony Lindgren wrote:
> 
> > * Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> > > 
> > > On Mon, 12 Dec 2011, Tero Kristo wrote:
> > > 
> > > So the patch description says:
> > > 
> > > > From: R, Govindraj <govindraj.raja@ti.com>
> > > > 
> > > > Add API to determine IO-PAD wakeup event status for a given
> > > > hwmod dynamic_mux pad.
> > > 
> > > But the code does:
> > > 
> > > > +	for (i = 0; i < hmux->nr_pads; i++) {
> > > > +		struct omap_device_pad *pad = &hmux->pads[i];
> > > 
> > > which is going to check all of the pads, not just the dynamic ones.
> > > 
> > > So it seems to me that we need to decide whether this code should be 
> > > testing all the pads, or just the dynamically remuxed ones.  The same 
> > > thing should be decided for the code in patch 1.
> > > 
> > > Na?vely it seems to me that we want to test all of the pads in both 
> > > patches 1 and 2, not just the dynamically remuxable ones.  Comments?
> > 
> > You're right, it should be only the dynamic ones.
> 
> Hmm, looks to me like it should check all of them?  Can't a pad be marked 
> with OMAP_DEVICE_PAD_WAKEUP, but not be marked with OMAP_DEVICE_PAD_REMUX?  
> In that case it would not end up on the dynamic list, right?

Hmm yes that's even more true :) Maybe the right approach would be to
copy the OMAP_DEVICE_PAD_WAKEUP pins also to the dynamic list to
avoid going through all of them.

Tony

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-13 22:48           ` Tony Lindgren
@ 2011-12-14  2:22             ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-14  2:22 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: R, Govindraj, Tero Kristo, linux-omap, linux-arm-kernel

On Tue, 13 Dec 2011, Tony Lindgren wrote:

> Hmm yes that's even more true :) Maybe the right approach would be to
> copy the OMAP_DEVICE_PAD_WAKEUP pins also to the dynamic list to
> avoid going through all of them.

Looking at this further, it seems that the best thing to do for now is to 
just add hwmod mux entries with OMAP_DEVICE_PAD_WAKEUP into the dynamic 
list.  Otherwise massive changes will be needed to omap_hwmod_mux() and 
related functions, since those currently only iterate over the dynamic mux 
entries.  Will post the mux patch to do this.


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-14  2:22             ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-14  2:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 13 Dec 2011, Tony Lindgren wrote:

> Hmm yes that's even more true :) Maybe the right approach would be to
> copy the OMAP_DEVICE_PAD_WAKEUP pins also to the dynamic list to
> avoid going through all of them.

Looking at this further, it seems that the best thing to do for now is to 
just add hwmod mux entries with OMAP_DEVICE_PAD_WAKEUP into the dynamic 
list.  Otherwise massive changes will be needed to omap_hwmod_mux() and 
related functions, since those currently only iterate over the dynamic mux 
entries.  Will post the mux patch to do this.


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-14  2:34     ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-14  2:34 UTC (permalink / raw)
  To: R, Govindraj, Tero Kristo; +Cc: linux-omap, linux-arm-kernel


Hi

so I've updated this patch to change the SCM PADCTRL registers if the 
hwmod is currently idle, and _set_idle_ioring_wakeup() is called.  
Otherwise calling _set_idle_ioring_wakeup() would be useless under those 
conditions, since the new I/O ring wakeup values wouldn't be written back 
to the hardware until the hwmod had gone through an idle->enabled and 
enabled->idle transition.  

Please try to consider the function's appropriate behavior under which 
these functions can be called...

Updated patch below.  Will update internally once I get Tero's 
Signed-off-by:.


- Paul

From: Govindraj R <govindraj.raja@ti.com>
Date: Tue, 13 Dec 2011 13:50:23 -0700
Subject: [PATCH] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup

Add API to enable IO pad wakeup capability based on mux pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability for the given
pads. Wakeup capability will be enabled/disabled during hwmod idle
transition based on whether wakeup_flag is set or cleared.  If the
hwmod is currently idled, and any mux values were changed by
_set_idle_ioring_wakeup(), the SCM PADCTRL registers will be updated.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
XXX Tero's sign-off?
[paul@pwsan.com: rearranged code to limit indentation; cleaned up
 function documentation; removed unused non-static functions; modified
 to search all hwmod pads, not just dynamic remuxing ones; modified to
 update SCM regs if hwmod is currently idle and any pads have changed]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   47 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 207a2ff..21ffd8a 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -381,6 +381,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 }
 
 /**
+ * _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
+ *
+ * Set or clear the I/O pad wakeup flag in the mux entries for the
+ * hwmod @oh.  This function changes the @oh->mux->pads_dynamic array
+ * in memory.  If the hwmod is currently idled, and the new idle
+ * values don't match the previous ones, this function will also
+ * update the SCM PADCTRL registers.  Otherwise, if the hwmod is not
+ * currently idled, this function won't touch the hardware: the new
+ * mux settings are written to the SCM PADCTRL registers when the
+ * hwmod is idled.  No return value.
+ */
+static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	struct omap_device_pad *pad;
+	bool change = false;
+	u16 prev_idle;
+	int j;
+
+	if (!oh->mux || !oh->mux->enabled)
+		return;
+
+	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+		pad = oh->mux->pads_dynamic[j];
+
+		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
+			continue;
+
+		prev_idle = pad->idle;
+
+		if (set_wake)
+			pad->idle |= OMAP_WAKEUP_EN;
+		else
+			pad->idle &= ~OMAP_WAKEUP_EN;
+
+		if (prev_idle != pad->idle)
+			change = true;
+	}
+
+	if (change && oh->_state == _HWMOD_STATE_IDLE)
+		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+}
+
+/**
  * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
  * @oh: struct omap_hwmod *
  *
@@ -2416,6 +2461,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_enable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_idle_ioring_wakeup(oh, true);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
@@ -2446,6 +2492,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_disable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_idle_ioring_wakeup(oh, false);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
@ 2011-12-14  2:34     ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-14  2:34 UTC (permalink / raw)
  To: linux-arm-kernel


Hi

so I've updated this patch to change the SCM PADCTRL registers if the 
hwmod is currently idle, and _set_idle_ioring_wakeup() is called.  
Otherwise calling _set_idle_ioring_wakeup() would be useless under those 
conditions, since the new I/O ring wakeup values wouldn't be written back 
to the hardware until the hwmod had gone through an idle->enabled and 
enabled->idle transition.  

Please try to consider the function's appropriate behavior under which 
these functions can be called...

Updated patch below.  Will update internally once I get Tero's 
Signed-off-by:.


- Paul

From: Govindraj R <govindraj.raja@ti.com>
Date: Tue, 13 Dec 2011 13:50:23 -0700
Subject: [PATCH] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup

Add API to enable IO pad wakeup capability based on mux pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability for the given
pads. Wakeup capability will be enabled/disabled during hwmod idle
transition based on whether wakeup_flag is set or cleared.  If the
hwmod is currently idled, and any mux values were changed by
_set_idle_ioring_wakeup(), the SCM PADCTRL registers will be updated.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
XXX Tero's sign-off?
[paul at pwsan.com: rearranged code to limit indentation; cleaned up
 function documentation; removed unused non-static functions; modified
 to search all hwmod pads, not just dynamic remuxing ones; modified to
 update SCM regs if hwmod is currently idle and any pads have changed]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   47 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 207a2ff..21ffd8a 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -381,6 +381,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 }
 
 /**
+ * _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
+ *
+ * Set or clear the I/O pad wakeup flag in the mux entries for the
+ * hwmod @oh.  This function changes the @oh->mux->pads_dynamic array
+ * in memory.  If the hwmod is currently idled, and the new idle
+ * values don't match the previous ones, this function will also
+ * update the SCM PADCTRL registers.  Otherwise, if the hwmod is not
+ * currently idled, this function won't touch the hardware: the new
+ * mux settings are written to the SCM PADCTRL registers when the
+ * hwmod is idled.  No return value.
+ */
+static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	struct omap_device_pad *pad;
+	bool change = false;
+	u16 prev_idle;
+	int j;
+
+	if (!oh->mux || !oh->mux->enabled)
+		return;
+
+	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+		pad = oh->mux->pads_dynamic[j];
+
+		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
+			continue;
+
+		prev_idle = pad->idle;
+
+		if (set_wake)
+			pad->idle |= OMAP_WAKEUP_EN;
+		else
+			pad->idle &= ~OMAP_WAKEUP_EN;
+
+		if (prev_idle != pad->idle)
+			change = true;
+	}
+
+	if (change && oh->_state == _HWMOD_STATE_IDLE)
+		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+}
+
+/**
  * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
  * @oh: struct omap_hwmod *
  *
@@ -2416,6 +2461,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_enable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_idle_ioring_wakeup(oh, true);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
@@ -2446,6 +2492,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_disable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	_set_idle_ioring_wakeup(oh, false);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-12 18:15   ` Tero Kristo
@ 2011-12-14  3:04     ` Paul Walmsley
  -1 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-14  3:04 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, linux-arm-kernel, R, Govindraj

Hi Tero

looking at this patch:

On Mon, 12 Dec 2011, Tero Kristo wrote:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to determine IO-PAD wakeup event status for a given
> hwmod dynamic_mux pad.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

It seems that your last patch drops the following code that this patch 
adds:

> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 8d37d83..d7f4623 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -2721,3 +2721,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
>  
>  	return 0;
>  }
> +
> +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
> +{
> +	if (oh && oh->mux)
> +		return omap_hwmod_mux_get_wake_status(oh->mux);
> +	return -EINVAL;
> +}
> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> index 8b372ed..1b81dfb 100644
> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> @@ -604,6 +604,7 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
>  
>  int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
>  
> +int omap_hwmod_pad_get_wakeup_status(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

It's best in these circumstances to modify this patch not to add the code 
in the first place.  Otherwise this creates needless churn which plenty of 
people are quite sensitized to.  So, dropping these from patch 2.


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-14  3:04     ` Paul Walmsley
  0 siblings, 0 replies; 54+ messages in thread
From: Paul Walmsley @ 2011-12-14  3:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero

looking at this patch:

On Mon, 12 Dec 2011, Tero Kristo wrote:

> From: R, Govindraj <govindraj.raja@ti.com>
> 
> Add API to determine IO-PAD wakeup event status for a given
> hwmod dynamic_mux pad.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

It seems that your last patch drops the following code that this patch 
adds:

> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 8d37d83..d7f4623 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -2721,3 +2721,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
>  
>  	return 0;
>  }
> +
> +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
> +{
> +	if (oh && oh->mux)
> +		return omap_hwmod_mux_get_wake_status(oh->mux);
> +	return -EINVAL;
> +}
> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> index 8b372ed..1b81dfb 100644
> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> @@ -604,6 +604,7 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
>  
>  int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
>  
> +int omap_hwmod_pad_get_wakeup_status(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

It's best in these circumstances to modify this patch not to add the code 
in the first place.  Otherwise this creates needless churn which plenty of 
people are quite sensitized to.  So, dropping these from patch 2.


- Paul

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-12-14  2:34     ` Paul Walmsley
@ 2011-12-14 10:02       ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-14 10:02 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: R, Govindraj, linux-omap, linux-arm-kernel

On Tue, 2011-12-13 at 19:34 -0700, Paul Walmsley wrote:
> Hi
> 
> so I've updated this patch to change the SCM PADCTRL registers if the 
> hwmod is currently idle, and _set_idle_ioring_wakeup() is called.  
> Otherwise calling _set_idle_ioring_wakeup() would be useless under those 
> conditions, since the new I/O ring wakeup values wouldn't be written back 
> to the hardware until the hwmod had gone through an idle->enabled and 
> enabled->idle transition.  
> 
> Please try to consider the function's appropriate behavior under which 
> these functions can be called...
> 
> Updated patch below.  Will update internally once I get Tero's 
> Signed-off-by:.

Hi Paul,

Patch looks okay to me, I also quickly tested it out and it works.

Signed-off-by: Tero Kristo <t-kristo@ti.com>

> 
> 
> - Paul
> 
> From: Govindraj R <govindraj.raja@ti.com>
> Date: Tue, 13 Dec 2011 13:50:23 -0700
> Subject: [PATCH] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup
> 
> Add API to enable IO pad wakeup capability based on mux pad and
> wake_up enable flag available from hwmod_mux initialization.
> 
> Use the wakeup_enable flag and enable wakeup capability for the given
> pads. Wakeup capability will be enabled/disabled during hwmod idle
> transition based on whether wakeup_flag is set or cleared.  If the
> hwmod is currently idled, and any mux values were changed by
> _set_idle_ioring_wakeup(), the SCM PADCTRL registers will be updated.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> XXX Tero's sign-off?
> [paul@pwsan.com: rearranged code to limit indentation; cleaned up
>  function documentation; removed unused non-static functions; modified
>  to search all hwmod pads, not just dynamic remuxing ones; modified to
>  update SCM regs if hwmod is currently idle and any pads have changed]
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod.c |   47 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 47 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 207a2ff..21ffd8a 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -381,6 +381,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
>  }
>  
>  /**
> + * _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
> + *
> + * Set or clear the I/O pad wakeup flag in the mux entries for the
> + * hwmod @oh.  This function changes the @oh->mux->pads_dynamic array
> + * in memory.  If the hwmod is currently idled, and the new idle
> + * values don't match the previous ones, this function will also
> + * update the SCM PADCTRL registers.  Otherwise, if the hwmod is not
> + * currently idled, this function won't touch the hardware: the new
> + * mux settings are written to the SCM PADCTRL registers when the
> + * hwmod is idled.  No return value.
> + */
> +static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
> +{
> +	struct omap_device_pad *pad;
> +	bool change = false;
> +	u16 prev_idle;
> +	int j;
> +
> +	if (!oh->mux || !oh->mux->enabled)
> +		return;
> +
> +	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
> +		pad = oh->mux->pads_dynamic[j];
> +
> +		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
> +			continue;
> +
> +		prev_idle = pad->idle;
> +
> +		if (set_wake)
> +			pad->idle |= OMAP_WAKEUP_EN;
> +		else
> +			pad->idle &= ~OMAP_WAKEUP_EN;
> +
> +		if (prev_idle != pad->idle)
> +			change = true;
> +	}
> +
> +	if (change && oh->_state == _HWMOD_STATE_IDLE)
> +		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
> +}
> +
> +/**
>   * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
>   * @oh: struct omap_hwmod *
>   *
> @@ -2416,6 +2461,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
>  	v = oh->_sysc_cache;
>  	_enable_wakeup(oh, &v);
>  	_write_sysconfig(v, oh);
> +	_set_idle_ioring_wakeup(oh, true);
>  	spin_unlock_irqrestore(&oh->_lock, flags);
>  
>  	return 0;
> @@ -2446,6 +2492,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
>  	v = oh->_sysc_cache;
>  	_disable_wakeup(oh, &v);
>  	_write_sysconfig(v, oh);
> +	_set_idle_ioring_wakeup(oh, false);
>  	spin_unlock_irqrestore(&oh->_lock, flags);
>  
>  	return 0;



^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup.
@ 2011-12-14 10:02       ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-14 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2011-12-13 at 19:34 -0700, Paul Walmsley wrote:
> Hi
> 
> so I've updated this patch to change the SCM PADCTRL registers if the 
> hwmod is currently idle, and _set_idle_ioring_wakeup() is called.  
> Otherwise calling _set_idle_ioring_wakeup() would be useless under those 
> conditions, since the new I/O ring wakeup values wouldn't be written back 
> to the hardware until the hwmod had gone through an idle->enabled and 
> enabled->idle transition.  
> 
> Please try to consider the function's appropriate behavior under which 
> these functions can be called...
> 
> Updated patch below.  Will update internally once I get Tero's 
> Signed-off-by:.

Hi Paul,

Patch looks okay to me, I also quickly tested it out and it works.

Signed-off-by: Tero Kristo <t-kristo@ti.com>

> 
> 
> - Paul
> 
> From: Govindraj R <govindraj.raja@ti.com>
> Date: Tue, 13 Dec 2011 13:50:23 -0700
> Subject: [PATCH] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup
> 
> Add API to enable IO pad wakeup capability based on mux pad and
> wake_up enable flag available from hwmod_mux initialization.
> 
> Use the wakeup_enable flag and enable wakeup capability for the given
> pads. Wakeup capability will be enabled/disabled during hwmod idle
> transition based on whether wakeup_flag is set or cleared.  If the
> hwmod is currently idled, and any mux values were changed by
> _set_idle_ioring_wakeup(), the SCM PADCTRL registers will be updated.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> XXX Tero's sign-off?
> [paul at pwsan.com: rearranged code to limit indentation; cleaned up
>  function documentation; removed unused non-static functions; modified
>  to search all hwmod pads, not just dynamic remuxing ones; modified to
>  update SCM regs if hwmod is currently idle and any pads have changed]
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod.c |   47 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 47 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 207a2ff..21ffd8a 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -381,6 +381,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
>  }
>  
>  /**
> + * _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
> + *
> + * Set or clear the I/O pad wakeup flag in the mux entries for the
> + * hwmod @oh.  This function changes the @oh->mux->pads_dynamic array
> + * in memory.  If the hwmod is currently idled, and the new idle
> + * values don't match the previous ones, this function will also
> + * update the SCM PADCTRL registers.  Otherwise, if the hwmod is not
> + * currently idled, this function won't touch the hardware: the new
> + * mux settings are written to the SCM PADCTRL registers when the
> + * hwmod is idled.  No return value.
> + */
> +static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
> +{
> +	struct omap_device_pad *pad;
> +	bool change = false;
> +	u16 prev_idle;
> +	int j;
> +
> +	if (!oh->mux || !oh->mux->enabled)
> +		return;
> +
> +	for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
> +		pad = oh->mux->pads_dynamic[j];
> +
> +		if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
> +			continue;
> +
> +		prev_idle = pad->idle;
> +
> +		if (set_wake)
> +			pad->idle |= OMAP_WAKEUP_EN;
> +		else
> +			pad->idle &= ~OMAP_WAKEUP_EN;
> +
> +		if (prev_idle != pad->idle)
> +			change = true;
> +	}
> +
> +	if (change && oh->_state == _HWMOD_STATE_IDLE)
> +		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
> +}
> +
> +/**
>   * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
>   * @oh: struct omap_hwmod *
>   *
> @@ -2416,6 +2461,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
>  	v = oh->_sysc_cache;
>  	_enable_wakeup(oh, &v);
>  	_write_sysconfig(v, oh);
> +	_set_idle_ioring_wakeup(oh, true);
>  	spin_unlock_irqrestore(&oh->_lock, flags);
>  
>  	return 0;
> @@ -2446,6 +2492,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
>  	v = oh->_sysc_cache;
>  	_disable_wakeup(oh, &v);
>  	_write_sysconfig(v, oh);
> +	_set_idle_ioring_wakeup(oh, false);
>  	spin_unlock_irqrestore(&oh->_lock, flags);
>  
>  	return 0;

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-14  3:04     ` Paul Walmsley
@ 2011-12-14 10:13       ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-14 10:13 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, R, Govindraj

On Tue, 2011-12-13 at 20:04 -0700, Paul Walmsley wrote:
> Hi Tero
> 
> looking at this patch:
> 
> On Mon, 12 Dec 2011, Tero Kristo wrote:
> 
> > From: R, Govindraj <govindraj.raja@ti.com>
> > 
> > Add API to determine IO-PAD wakeup event status for a given
> > hwmod dynamic_mux pad.
> > 
> > Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> 
> It seems that your last patch drops the following code that this patch 
> adds:

Hmm yea true, it seems like the code in patch 2 does not exist anymore
after patch 8, and well, the code in patch 2 was never used for anything
anyway. Sorry for not spotting this myself, I added patch 8 in hurry to
this set.

> 
> > diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> > index 8d37d83..d7f4623 100644
> > --- a/arch/arm/mach-omap2/omap_hwmod.c
> > +++ b/arch/arm/mach-omap2/omap_hwmod.c
> > @@ -2721,3 +2721,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
> >  
> >  	return 0;
> >  }
> > +
> > +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
> > +{
> > +	if (oh && oh->mux)
> > +		return omap_hwmod_mux_get_wake_status(oh->mux);
> > +	return -EINVAL;
> > +}
> > diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> > index 8b372ed..1b81dfb 100644
> > --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> > +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> > @@ -604,6 +604,7 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
> >  
> >  int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
> >  
> > +int omap_hwmod_pad_get_wakeup_status(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
> 
> It's best in these circumstances to modify this patch not to add the code 
> in the first place.  Otherwise this creates needless churn which plenty of 
> people are quite sensitized to.  So, dropping these from patch 2.

Yeah, good call.

-Tero



^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-14 10:13       ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-14 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2011-12-13 at 20:04 -0700, Paul Walmsley wrote:
> Hi Tero
> 
> looking at this patch:
> 
> On Mon, 12 Dec 2011, Tero Kristo wrote:
> 
> > From: R, Govindraj <govindraj.raja@ti.com>
> > 
> > Add API to determine IO-PAD wakeup event status for a given
> > hwmod dynamic_mux pad.
> > 
> > Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> 
> It seems that your last patch drops the following code that this patch 
> adds:

Hmm yea true, it seems like the code in patch 2 does not exist anymore
after patch 8, and well, the code in patch 2 was never used for anything
anyway. Sorry for not spotting this myself, I added patch 8 in hurry to
this set.

> 
> > diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> > index 8d37d83..d7f4623 100644
> > --- a/arch/arm/mach-omap2/omap_hwmod.c
> > +++ b/arch/arm/mach-omap2/omap_hwmod.c
> > @@ -2721,3 +2721,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
> >  
> >  	return 0;
> >  }
> > +
> > +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
> > +{
> > +	if (oh && oh->mux)
> > +		return omap_hwmod_mux_get_wake_status(oh->mux);
> > +	return -EINVAL;
> > +}
> > diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> > index 8b372ed..1b81dfb 100644
> > --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> > +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> > @@ -604,6 +604,7 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
> >  
> >  int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
> >  
> > +int omap_hwmod_pad_get_wakeup_status(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
> 
> It's best in these circumstances to modify this patch not to add the code 
> in the first place.  Otherwise this creates needless churn which plenty of 
> people are quite sensitized to.  So, dropping these from patch 2.

Yeah, good call.

-Tero

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-13 22:48           ` Tony Lindgren
@ 2011-12-14 10:17             ` Tero Kristo
  -1 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-14 10:17 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Paul Walmsley, R, Govindraj, linux-omap, linux-arm-kernel

On Tue, 2011-12-13 at 14:48 -0800, Tony Lindgren wrote:
> * Paul Walmsley <paul@pwsan.com> [111213 14:06]:
> > On Tue, 13 Dec 2011, Tony Lindgren wrote:
> > 
> > > * Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> > > > 
> > > > On Mon, 12 Dec 2011, Tero Kristo wrote:
> > > > 
> > > > So the patch description says:
> > > > 
> > > > > From: R, Govindraj <govindraj.raja@ti.com>
> > > > > 
> > > > > Add API to determine IO-PAD wakeup event status for a given
> > > > > hwmod dynamic_mux pad.
> > > > 
> > > > But the code does:
> > > > 
> > > > > +	for (i = 0; i < hmux->nr_pads; i++) {
> > > > > +		struct omap_device_pad *pad = &hmux->pads[i];
> > > > 
> > > > which is going to check all of the pads, not just the dynamic ones.
> > > > 
> > > > So it seems to me that we need to decide whether this code should be 
> > > > testing all the pads, or just the dynamically remuxed ones.  The same 
> > > > thing should be decided for the code in patch 1.
> > > > 
> > > > Naïvely it seems to me that we want to test all of the pads in both 
> > > > patches 1 and 2, not just the dynamically remuxable ones.  Comments?
> > > 
> > > You're right, it should be only the dynamic ones.
> > 
> > Hmm, looks to me like it should check all of them?  Can't a pad be marked 
> > with OMAP_DEVICE_PAD_WAKEUP, but not be marked with OMAP_DEVICE_PAD_REMUX?  
> > In that case it would not end up on the dynamic list, right?
> 
> Hmm yes that's even more true :) Maybe the right approach would be to
> copy the OMAP_DEVICE_PAD_WAKEUP pins also to the dynamic list to
> avoid going through all of them.

Yea, all pads that have WAKEUP capability should be checked. Not sure if
this comment is valid anymore seeing patch 2 is kind of irrelevant with
patch 8, but the code that scans wakeups should check them all.

-Tero


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status
@ 2011-12-14 10:17             ` Tero Kristo
  0 siblings, 0 replies; 54+ messages in thread
From: Tero Kristo @ 2011-12-14 10:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2011-12-13 at 14:48 -0800, Tony Lindgren wrote:
> * Paul Walmsley <paul@pwsan.com> [111213 14:06]:
> > On Tue, 13 Dec 2011, Tony Lindgren wrote:
> > 
> > > * Paul Walmsley <paul@pwsan.com> [111213 13:44]:
> > > > 
> > > > On Mon, 12 Dec 2011, Tero Kristo wrote:
> > > > 
> > > > So the patch description says:
> > > > 
> > > > > From: R, Govindraj <govindraj.raja@ti.com>
> > > > > 
> > > > > Add API to determine IO-PAD wakeup event status for a given
> > > > > hwmod dynamic_mux pad.
> > > > 
> > > > But the code does:
> > > > 
> > > > > +	for (i = 0; i < hmux->nr_pads; i++) {
> > > > > +		struct omap_device_pad *pad = &hmux->pads[i];
> > > > 
> > > > which is going to check all of the pads, not just the dynamic ones.
> > > > 
> > > > So it seems to me that we need to decide whether this code should be 
> > > > testing all the pads, or just the dynamically remuxed ones.  The same 
> > > > thing should be decided for the code in patch 1.
> > > > 
> > > > Na?vely it seems to me that we want to test all of the pads in both 
> > > > patches 1 and 2, not just the dynamically remuxable ones.  Comments?
> > > 
> > > You're right, it should be only the dynamic ones.
> > 
> > Hmm, looks to me like it should check all of them?  Can't a pad be marked 
> > with OMAP_DEVICE_PAD_WAKEUP, but not be marked with OMAP_DEVICE_PAD_REMUX?  
> > In that case it would not end up on the dynamic list, right?
> 
> Hmm yes that's even more true :) Maybe the right approach would be to
> copy the OMAP_DEVICE_PAD_WAKEUP pins also to the dynamic list to
> avoid going through all of them.

Yea, all pads that have WAKEUP capability should be checked. Not sure if
this comment is valid anymore seeing patch 2 is kind of irrelevant with
patch 8, but the code that scans wakeups should check them all.

-Tero

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2011-12-14 10:17 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-12 18:15 [PATCHv11 0/8] OMAP3+: PRCM chain handler Tero Kristo
2011-12-12 18:15 ` Tero Kristo
2011-12-12 18:15 ` [PATCHv11 1/8] ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-13 20:51   ` Paul Walmsley
2011-12-13 20:51     ` Paul Walmsley
2011-12-13 21:04   ` Paul Walmsley
2011-12-13 21:04     ` Paul Walmsley
2011-12-13 21:33     ` Paul Walmsley
2011-12-13 21:33       ` Paul Walmsley
2011-12-14  2:34   ` Paul Walmsley
2011-12-14  2:34     ` Paul Walmsley
2011-12-14 10:02     ` Tero Kristo
2011-12-14 10:02       ` Tero Kristo
2011-12-12 18:15 ` [PATCHv11 2/8] ARM: OMAP2+: hwmod: Add API to check IO PAD wakeup status Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-13  0:28   ` Tony Lindgren
2011-12-13  0:28     ` Tony Lindgren
2011-12-13 22:16   ` Paul Walmsley
2011-12-13 22:16     ` Paul Walmsley
2011-12-13 22:28     ` Tony Lindgren
2011-12-13 22:28       ` Tony Lindgren
2011-12-13 22:38       ` Paul Walmsley
2011-12-13 22:38         ` Paul Walmsley
2011-12-13 22:48         ` Tony Lindgren
2011-12-13 22:48           ` Tony Lindgren
2011-12-14  2:22           ` Paul Walmsley
2011-12-14  2:22             ` Paul Walmsley
2011-12-14 10:17           ` Tero Kristo
2011-12-14 10:17             ` Tero Kristo
2011-12-14  3:04   ` Paul Walmsley
2011-12-14  3:04     ` Paul Walmsley
2011-12-14 10:13     ` Tero Kristo
2011-12-14 10:13       ` Tero Kristo
2011-12-12 18:15 ` [PATCHv11 3/8] ARM: OMAP: prm: add support for chain interrupt handler Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-13  0:27   ` Tony Lindgren
2011-12-13  0:27     ` Tony Lindgren
2011-12-12 18:15 ` [PATCHv11 4/8] ARM: OMAP: prcm: add suspend prepare / finish support Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-12 18:15 ` [PATCHv11 5/8] ARM: OMAP2+: mux: add support for PAD wakeup interrupts Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-13  0:24   ` Tony Lindgren
2011-12-13  0:24     ` Tony Lindgren
2011-12-12 18:15 ` [PATCHv11 6/8] ARM: OMAP3: pm: use prcm chain handler Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-12 18:15 ` [PATCHv11 7/8] ARM: OMAP3: pm: do not enable PRCM MPU interrupts manually Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-12 18:15 ` [PATCHv11 8/8] ARM: OMAP: mux: add support for selecting mpu_irq for each wakeup pad Tero Kristo
2011-12-12 18:15   ` Tero Kristo
2011-12-13  0:25   ` Tony Lindgren
2011-12-13  0:25     ` Tony Lindgren
2011-12-13  0:33 ` [PATCHv11 0/8] OMAP3+: PRCM chain handler Kevin Hilman
2011-12-13  0:33   ` Kevin Hilman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.