linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv10 00/14] PRCM chain handler
@ 2011-12-09 14:27 Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 01/14] OMAP2+: hwmod: Add API to enable IO ring wakeup Tero Kristo
                   ` (14 more replies)
  0 siblings, 15 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

Hi,

Once more a new version, it was decided that the PRM driver will be
dropped for now, and we will have the chain handler support under
mach-omap2 directory. This will most likely be addressed in future.
Other than that, the code is pretty close to what was in version 9,
just location has changed from /drivers/mfd to /arch/arm/mach-omap2.

Tested with omap3 beagleboard, with dynamic idle and suspend, both
retention and off. omap4 should not be an issue seeing the code is
close to what was in version 9.

TEMP patches can be ignored, they are provided only for testing
purposes, and shall be replaced by uart runtime support.

-Tero


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

* [PATCHv10 01/14] OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 02/14] OMAP2+: hwmod: Add API to check IO PAD wakeup status Tero Kristo
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson; +Cc: 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] 24+ messages in thread

* [PATCHv10 02/14] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 01/14] OMAP2+: hwmod: Add API to enable IO ring wakeup Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 03/14] omap: prm: add support for chain interrupt handler Tero Kristo
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson; +Cc: 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] 24+ messages in thread

* [PATCHv10 03/14] omap: prm: add support for chain interrupt handler
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 01/14] OMAP2+: hwmod: Add API to enable IO ring wakeup Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 02/14] OMAP2+: hwmod: Add API to check IO PAD wakeup status Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 04/14] omap: prm: add support for suspend prepare and finish callbacks Tero Kristo
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson
  Cc: Avinash.H.M, 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      |   20 +++
 4 files changed, 299 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..f242f2e 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 +134,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] 24+ messages in thread

* [PATCHv10 04/14] omap: prm: add support for suspend prepare and finish callbacks
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (2 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 03/14] omap: prm: add support for chain interrupt handler Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 23:04   ` Kevin Hilman
  2011-12-09 14:27 ` [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts Tero Kristo
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

These are needed because runtime PM is disabled during suspend, and
it is bad if we get interrupts from the PRCM chain handler during it.
This patch masks all the PRCM interrupt events, but does not ack them,
if an interrupt is received during suspend. 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.

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] 24+ messages in thread

* [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (3 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 04/14] omap: prm: add support for suspend prepare and finish callbacks Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 23:13   ` Kevin Hilman
  2011-12-09 14:27 ` [PATCHv10 06/14] omap3: pm: use prcm chain handler Tero Kristo
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

OMAP mux now provides a service routine to parse pending wakeup events
and to call registered ISR whenever active wakeups are detected. This
routine is called directly from PRCM interrupt handler.

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] 24+ messages in thread

* [PATCHv10 06/14] omap3: pm: use prcm chain handler
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (4 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 23:23   ` Kevin Hilman
  2011-12-09 14:27 ` [PATCHv10 07/14] OMAP3: pm: do not enable PRCM MPU interrupts manually Tero Kristo
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

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.

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

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index efa6649..f6cbb48 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,20 @@ 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, 0, "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, "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] 24+ messages in thread

* [PATCHv10 07/14] OMAP3: pm: do not enable PRCM MPU interrupts manually
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (5 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 06/14] omap3: pm: use prcm chain handler Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 08/14] TEMP: serial: added mux support Tero Kristo
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

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 f6cbb48..9e20ecb 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] 24+ messages in thread

* [PATCHv10 08/14] TEMP: serial: added mux support
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (6 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 07/14] OMAP3: pm: do not enable PRCM MPU interrupts manually Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 09/14] TEMP: 4430sdp: use common serial init with " Tero Kristo
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

Just for PRCM chain handler testing purposes. This should be replaced with
a proper implementation.

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

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 9992dbf..b479b3f 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -839,17 +839,84 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
  * can call this function when they want to have default behaviour
  * for serial ports (e.g initialize them all as serial ports).
  */
+
+struct serial_mux_conf {
+	char *name;
+	int omap3_mux;
+	int omap4_mux;
+};
+
+#define OMAP3_SERIAL_MUX_IN_PU (OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0)
+#define OMAP3_SERIAL_MUX_IN_PD (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0)
+#define OMAP3_SERIAL_MUX_IN (OMAP_PIN_INPUT | OMAP_MUX_MODE0)
+#define OMAP3_SERIAL_MUX_OUT (OMAP_PIN_OUTPUT | OMAP_MUX_MODE0)
+#define OMAP4_SERIAL_MUX_IN_PU (OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0)
+#define OMAP4_SERIAL_MUX_OUT (OMAP_PIN_OUTPUT | OMAP_MUX_MODE0)
+#define OMAP4_SERIAL_MUX_IN (OMAP_PIN_INPUT | OMAP_MUX_MODE0)
+#define SERIAL_DISABLED OMAP_MUX_MODE7
+
+#define OMAP_SERIAL_NUM_PADS_PER_PORT 4
+
+static const struct serial_mux_conf serial_mux_data[] = {
+	{ "uart1_cts.uart1_cts", OMAP3_SERIAL_MUX_IN, SERIAL_DISABLED, },
+	{ "uart1_rts.uart1_rts", OMAP3_SERIAL_MUX_OUT, SERIAL_DISABLED, },
+	{ "uart1_rx.uart1_rx", OMAP3_SERIAL_MUX_IN, SERIAL_DISABLED, },
+	{ "uart1_tx.uart1_tx", OMAP3_SERIAL_MUX_OUT, SERIAL_DISABLED, },
+	{ "uart2_cts.uart2_cts", OMAP3_SERIAL_MUX_IN,
+		OMAP4_SERIAL_MUX_IN_PU, },
+	{ "uart2_rts.uart2_rts", OMAP3_SERIAL_MUX_OUT, OMAP4_SERIAL_MUX_OUT, },
+	{ "uart2_rx.uart2_rx", OMAP3_SERIAL_MUX_IN, OMAP4_SERIAL_MUX_IN_PU, },
+	{ "uart2_tx.uart2_tx", OMAP3_SERIAL_MUX_OUT, OMAP4_SERIAL_MUX_OUT },
+	{ "uart3_cts_rctx.uart3_cts_rctx", OMAP3_SERIAL_MUX_IN_PD,
+		OMAP4_SERIAL_MUX_IN_PU, },
+	{ "uart3_rts_sd.uart3_rts_sd", OMAP3_SERIAL_MUX_OUT,
+		OMAP4_SERIAL_MUX_OUT, },
+	{ "uart3_rx_irrx.uart3_rx_irrx", OMAP3_SERIAL_MUX_IN,
+		OMAP4_SERIAL_MUX_IN, },
+	{ "uart3_tx_irtx.uart3_tx_irtx", OMAP3_SERIAL_MUX_OUT,
+		OMAP4_SERIAL_MUX_OUT, },
+	{ "uart4_rx.uart4_rx", SERIAL_DISABLED, OMAP4_SERIAL_MUX_IN, },
+	{ "uart4_tx.uart4_tx", SERIAL_DISABLED, OMAP4_SERIAL_MUX_OUT, },
+	{ NULL, SERIAL_DISABLED, SERIAL_DISABLED, },
+	{ NULL, SERIAL_DISABLED, SERIAL_DISABLED, },
+};
+
 void __init omap_serial_init(void)
 {
 	struct omap_uart_state *uart;
 	struct omap_board_data bdata;
+	struct omap_device_pad *pads;
+	int idx;
+	int i;
 
+	pads = kmalloc(sizeof(struct omap_device_pad) * 4, GFP_KERNEL);
 	list_for_each_entry(uart, &uart_list, node) {
 		bdata.id = uart->num;
 		bdata.flags = 0;
-		bdata.pads = NULL;
 		bdata.pads_cnt = 0;
+		bdata.pads = pads;
+
+		for (i = 0; i < OMAP_SERIAL_NUM_PADS_PER_PORT; i++) {
+			idx = bdata.id * OMAP_SERIAL_NUM_PADS_PER_PORT + i;
+			pads[i].name = serial_mux_data[idx].name;
+			pads[i].enable = 0;
+			pads[i].idle = 0;
+			pads[i].flags = 0;
+			if (cpu_is_omap34xx())
+				pads[i].enable = serial_mux_data[idx].omap3_mux;
+			if (cpu_is_omap44xx())
+				pads[i].enable = serial_mux_data[idx].omap4_mux;
+			if (pads[i].enable != SERIAL_DISABLED)
+				bdata.pads_cnt++;
+			if (pads[i].enable & OMAP_PIN_INPUT) {
+				pads[i].flags = OMAP_DEVICE_PAD_REMUX |
+					OMAP_DEVICE_PAD_WAKEUP;
+			}
+			pads[i].idle = pads[i].enable;
+		}
+		if (bdata.pads_cnt == 0)
+			bdata.pads = NULL;
 		omap_serial_init_port(&bdata);
-
 	}
+	kfree(pads);
 }
-- 
1.7.4.1


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

* [PATCHv10 09/14] TEMP: 4430sdp: use common serial init with mux support
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (7 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 08/14] TEMP: serial: added mux support Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 10/14] TEMP: mux: added trace for io wkup event Tero Kristo
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

Temporary testing related patch, not meant for integration.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/board-4430sdp.c |   12 +-----------
 1 files changed, 1 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 5156468..7852da4 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -886,17 +886,7 @@ static struct omap_board_data serial4_data __initdata = {
 
 static inline void board_serial_init(void)
 {
-	struct omap_board_data bdata;
-	bdata.flags	= 0;
-	bdata.pads	= NULL;
-	bdata.pads_cnt	= 0;
-	bdata.id	= 0;
-	/* pass dummy data for UART1 */
-	omap_serial_init_port(&bdata);
-
-	omap_serial_init_port(&serial2_data);
-	omap_serial_init_port(&serial3_data);
-	omap_serial_init_port(&serial4_data);
+	omap_serial_init();
 }
 #else
 #define board_mux	NULL
-- 
1.7.4.1


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

* [PATCHv10 10/14] TEMP: mux: added trace for io wkup event
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (8 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 09/14] TEMP: 4430sdp: use common serial init with " Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 11/14] TEMP: OMAP3: pm: remove serial resume / idle calls from idle path Tero Kristo
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson

Temporary patch for testing purposes, not meant for integration.

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

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 0d1962e..0233cb8 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -376,6 +376,8 @@ bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
 					pad->mux->reg_offset);
 			if (val & OMAP_WAKEUP_EVENT) {
 				ret = true;
+				pr_info("wkup detected: %04x\n",
+					pad->mux->reg_offset);
 				break;
 			}
 		}
-- 
1.7.4.1


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

* [PATCHv10 11/14] TEMP: OMAP3: pm: remove serial resume / idle calls from idle path
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (9 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 10/14] TEMP: mux: added trace for io wkup event Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 12/14] TEMP: OMAP3: serial: made serial to work properly with PRCM chain handler Tero Kristo
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson; +Cc: Govindraj.R

This is no longer needed as it will be handled within serial driver itself.
This part should be properly handled with serial runtime support.

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

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 9e20ecb..995a727 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -336,20 +336,11 @@ void omap_sram_idle(void)
 			omap3_enable_io_chain();
 	}
 
-	/* Block console output in case it is on one of the OMAP UARTs */
-	if (!is_suspending())
-		if (per_next_state < PWRDM_POWER_ON ||
-		    core_next_state < PWRDM_POWER_ON)
-			if (!console_trylock())
-				goto console_still_active;
-
 	pwrdm_pre_transition();
 
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
 		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
-		omap_uart_prepare_idle(2);
-		omap_uart_prepare_idle(3);
 		omap2_gpio_prepare_for_idle(per_going_off);
 		if (per_next_state == PWRDM_POWER_OFF)
 				omap3_per_save_context();
@@ -357,8 +348,6 @@ void omap_sram_idle(void)
 
 	/* CORE */
 	if (core_next_state < PWRDM_POWER_ON) {
-		omap_uart_prepare_idle(0);
-		omap_uart_prepare_idle(1);
 		if (core_next_state == PWRDM_POWER_OFF) {
 			omap3_core_save_context();
 			omap3_cm_save_context();
@@ -407,8 +396,6 @@ void omap_sram_idle(void)
 			omap3_sram_restore_context();
 			omap2_sms_restore_context();
 		}
-		omap_uart_resume_idle(0);
-		omap_uart_resume_idle(1);
 		if (core_next_state == PWRDM_POWER_OFF)
 			omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
 					       OMAP3430_GR_MOD,
@@ -424,14 +411,8 @@ void omap_sram_idle(void)
 		omap2_gpio_resume_after_idle();
 		if (per_prev_state == PWRDM_POWER_OFF)
 			omap3_per_restore_context();
-		omap_uart_resume_idle(2);
-		omap_uart_resume_idle(3);
 	}
 
-	if (!is_suspending())
-		console_unlock();
-
-console_still_active:
 	/* Disable IO-PAD and IO-CHAIN wakeup */
 	if (omap3_has_io_wakeup() &&
 	    (per_next_state < PWRDM_POWER_ON ||
-- 
1.7.4.1


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

* [PATCHv10 12/14] TEMP: OMAP3: serial: made serial to work properly with PRCM chain handler
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (10 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 11/14] TEMP: OMAP3: pm: remove serial resume / idle calls from idle path Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 13/14] TEMP: OMAP: serial: remove padconf hacks Tero Kristo
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson; +Cc: Govindraj.R

This patch is just a temporary hack to allow serial to work properly with
the PRCM chain handler. Should be replaced with a proper implementation
by serial runtime PM support.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c     |   29 +++++++++--------------------
 drivers/tty/serial/omap-serial.c |    2 ++
 2 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index b479b3f..13008f5 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -39,6 +39,7 @@
 #include <plat/dma.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <plat/prcm.h>
 
 #include "prm2xxx_3xxx.h"
 #include "pm.h"
@@ -358,6 +359,7 @@ static void omap_uart_allow_sleep(struct omap_uart_state *uart)
 	omap_uart_smart_idle_enable(uart, 1);
 	uart->can_sleep = 1;
 	del_timer(&uart->timer);
+	omap_uart_disable_clocks(uart);
 }
 
 static void omap_uart_idle_timer(unsigned long data)
@@ -369,36 +371,23 @@ static void omap_uart_idle_timer(unsigned long data)
 
 void omap_uart_prepare_idle(int num)
 {
-	struct omap_uart_state *uart;
-
-	list_for_each_entry(uart, &uart_list, node) {
-		if (num == uart->num && uart->can_sleep) {
-			omap_uart_disable_clocks(uart);
-			return;
-		}
-	}
 }
 
 void omap_uart_resume_idle(int num)
 {
 	struct omap_uart_state *uart;
+	u32 wkst;
 
 	list_for_each_entry(uart, &uart_list, node) {
 		if (num == uart->num && uart->can_sleep) {
-			omap_uart_enable_clocks(uart);
+			omap_uart_block_sleep(uart);
 
-			/* Check for IO pad wakeup */
-			if (cpu_is_omap34xx() && uart->padconf) {
-				u16 p = omap_ctrl_readw(uart->padconf);
-
-				if (p & OMAP3_PADCONF_WAKEUPEVENT0)
-					omap_uart_block_sleep(uart);
+			/* Check for normal UART wakeup (and clear it) */
+			if (uart->wk_st && uart->wk_mask) {
+				wkst = __raw_readl(uart->wk_st) & uart->wk_mask;
+				if (wkst)
+					__raw_writel(wkst, uart->wk_st);
 			}
-
-			/* Check for normal UART wakeup */
-			if (__raw_readl(uart->wk_st) & uart->wk_mask)
-				omap_uart_block_sleep(uart);
-			return;
 		}
 	}
 }
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 5e713d3..84548ca 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -51,12 +51,14 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up);
 
 static inline unsigned int serial_in(struct uart_omap_port *up, int offset)
 {
+	omap_uart_resume_idle(up->pdev->id);
 	offset <<= up->port.regshift;
 	return readw(up->port.membase + offset);
 }
 
 static inline void serial_out(struct uart_omap_port *up, int offset, int value)
 {
+	omap_uart_resume_idle(up->pdev->id);
 	offset <<= up->port.regshift;
 	writew(value, up->port.membase + offset);
 }
-- 
1.7.4.1


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

* [PATCHv10 13/14] TEMP: OMAP: serial: remove padconf hacks
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (11 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 12/14] TEMP: OMAP3: serial: made serial to work properly with PRCM chain handler Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 14:27 ` [PATCHv10 14/14] TEMP: OMAP device: change pr_warnings to pr_debugs Tero Kristo
  2011-12-09 22:36 ` [PATCHv10 00/14] PRCM chain handler Kevin Hilman
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson; +Cc: Govindraj.R

These are no longer needed as omap_hwmod takes care of multiplexing of pads.
Should be handled properly with serial runtime PM support patches.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c |   25 +------------------------
 1 files changed, 1 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 13008f5..525d2cf 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -73,7 +73,6 @@ struct omap_uart_state {
 	void __iomem *wk_st;
 	void __iomem *wk_en;
 	u32 wk_mask;
-	u32 padconf;
 	u32 dma_enabled;
 
 	struct clk *ick;
@@ -287,13 +286,6 @@ static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
 		v |= uart->wk_mask;
 		__raw_writel(v, uart->wk_en);
 	}
-
-	/* Ensure IOPAD wake-enables are set */
-	if (cpu_is_omap34xx() && uart->padconf) {
-		u16 v = omap_ctrl_readw(uart->padconf);
-		v |= OMAP3_PADCONF_WAKEUPENABLE0;
-		omap_ctrl_writew(v, uart->padconf);
-	}
 }
 
 static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
@@ -304,13 +296,6 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
 		v &= ~uart->wk_mask;
 		__raw_writel(v, uart->wk_en);
 	}
-
-	/* Ensure IOPAD wake-enables are cleared */
-	if (cpu_is_omap34xx() && uart->padconf) {
-		u16 v = omap_ctrl_readw(uart->padconf);
-		v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
-		omap_ctrl_writew(v, uart->padconf);
-	}
 }
 
 static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
@@ -456,7 +441,6 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 	if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
 		u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
 		u32 wk_mask = 0;
-		u32 padconf = 0;
 
 		/* XXX These PRM accesses do not belong here */
 		uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
@@ -464,23 +448,18 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 		switch (uart->num) {
 		case 0:
 			wk_mask = OMAP3430_ST_UART1_MASK;
-			padconf = 0x182;
 			break;
 		case 1:
 			wk_mask = OMAP3430_ST_UART2_MASK;
-			padconf = 0x17a;
 			break;
 		case 2:
 			wk_mask = OMAP3430_ST_UART3_MASK;
-			padconf = 0x19e;
 			break;
 		case 3:
 			wk_mask = OMAP3630_ST_UART4_MASK;
-			padconf = 0x0d2;
 			break;
 		}
 		uart->wk_mask = wk_mask;
-		uart->padconf = padconf;
 	} else if (cpu_is_omap24xx()) {
 		u32 wk_mask = 0;
 		u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
@@ -510,7 +489,6 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 		uart->wk_en = NULL;
 		uart->wk_st = NULL;
 		uart->wk_mask = 0;
-		uart->padconf = 0;
 	}
 
 	uart->irqflags |= IRQF_SHARED;
@@ -810,8 +788,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	console_unlock();
 
-	if ((cpu_is_omap34xx() && uart->padconf) ||
-	    (uart->wk_en && uart->wk_mask)) {
+	if (uart->oh->mux || (uart->wk_en && uart->wk_mask)) {
 		device_init_wakeup(&pdev->dev, true);
 		DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout);
 	}
-- 
1.7.4.1


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

* [PATCHv10 14/14] TEMP: OMAP device: change pr_warnings to pr_debugs
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (12 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 13/14] TEMP: OMAP: serial: remove padconf hacks Tero Kristo
@ 2011-12-09 14:27 ` Tero Kristo
  2011-12-09 22:36 ` [PATCHv10 00/14] PRCM chain handler Kevin Hilman
  14 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-09 14:27 UTC (permalink / raw)
  To: linux-omap, khilman, paul, b-cousson; +Cc: Govindraj.R

Prevents a hang when omap_device would want to print something for
serial console device while enabling / disabling its clocks.
Should be handled properly by serial runtime PM support.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/plat-omap/omap_device.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index f72fafc..1cd5f74 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -164,7 +164,7 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
 					"%d: %llu\n",
 					od->pm_lat_level, act_lat);
 			} else
-				dev_warn(&od->pdev->dev,
+				dev_dbg(&od->pdev->dev,
 					 "activate latency %d "
 					 "higher than exptected. (%llu > %d)\n",
 					 od->pm_lat_level, act_lat,
@@ -231,7 +231,7 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
 					"%d: %llu\n",
 					od->pm_lat_level, deact_lat);
 			} else
-				dev_warn(&od->pdev->dev,
+				dev_dbg(&od->pdev->dev,
 					 "deactivate latency %d "
 					 "higher than exptected. (%llu > %d)\n",
 					 od->pm_lat_level, deact_lat,
-- 
1.7.4.1


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

* Re: [PATCHv10 00/14] PRCM chain handler
  2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
                   ` (13 preceding siblings ...)
  2011-12-09 14:27 ` [PATCHv10 14/14] TEMP: OMAP device: change pr_warnings to pr_debugs Tero Kristo
@ 2011-12-09 22:36 ` Kevin Hilman
  2011-12-12  9:56   ` Tero Kristo
  14 siblings, 1 reply; 24+ messages in thread
From: Kevin Hilman @ 2011-12-09 22:36 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, paul, b-cousson

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

> Once more a new version, it was decided that the PRM driver will be
> dropped for now, and we will have the chain handler support under
> mach-omap2 directory. This will most likely be addressed in future.

Just to clarify for others: We decided that since the PRM driver is
going to take some more time to sort out, we would at least get the
chained IRQ support in now so we can unblock drivers that need it for
wakeup support (like UART, USB host, etc.)

> Other than that, the code is pretty close to what was in version 9,
> just location has changed from /drivers/mfd to /arch/arm/mach-omap2.
>
> Tested with omap3 beagleboard, with dynamic idle and suspend, both
> retention and off. omap4 should not be an issue seeing the code is
> close to what was in version 9.
>
> TEMP patches can be ignored, they are provided only for testing
> purposes, and shall be replaced by uart runtime support.

Can you repost a series without the TEMP patches, and Cc
linux-arm-kernel as well.

For testing purposes, you can make a branch available with the temp
patches included, and mention it in the changelog.

Thanks,

Kevin

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

* Re: [PATCHv10 04/14] omap: prm: add support for suspend prepare and finish callbacks
  2011-12-09 14:27 ` [PATCHv10 04/14] omap: prm: add support for suspend prepare and finish callbacks Tero Kristo
@ 2011-12-09 23:04   ` Kevin Hilman
  2011-12-12  9:57     ` Tero Kristo
  0 siblings, 1 reply; 24+ messages in thread
From: Kevin Hilman @ 2011-12-09 23:04 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, paul, b-cousson

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

> These are needed because runtime PM is disabled during suspend, and
> it is bad if we get interrupts from the PRCM chain handler during it.
> This patch masks all the PRCM interrupt events, but does not ack them,
> if an interrupt is received during suspend. 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.

You might just update this changelog to clarify why you're using the the
driver-specific prepare & complete terminology whereas this code is
using begin/finish hooks as part of platform_pm_ops.

IOW, state that this will soon be becoming a real driver, so you're
using the driver terminology.

Also note that subject uses prepare & finish instead of prepare & complete.

Kevin


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

* Re: [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts
  2011-12-09 14:27 ` [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts Tero Kristo
@ 2011-12-09 23:13   ` Kevin Hilman
  2011-12-12 10:01     ` Tero Kristo
  0 siblings, 1 reply; 24+ messages in thread
From: Kevin Hilman @ 2011-12-09 23:13 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, paul, b-cousson

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

> OMAP mux now provides a service routine to parse pending wakeup events
> and to call registered ISR whenever active wakeups are detected. 

Good.

> This routine is called directly from PRCM interrupt handler.

I think this comment is out of date with the code, since you're now
using a shared IRQ and the interrupt is directly called from the IRQ
core.

I'd update the changelog here just commenting on what this IRQ is shared
with, and how the interrupts are shared.

Also, a question on optimization.  For every IO wakeup, this will go
through the list of *all* enabled hwmods.  This could be pretty expensive
with lots of wakeups.  Maybe we should have another flag for hwmods that
have wakeups enabled so walking the list of potential wakeup-capable
hwmods will be as fast as possible.

Kevin


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

* Re: [PATCHv10 06/14] omap3: pm: use prcm chain handler
  2011-12-09 14:27 ` [PATCHv10 06/14] omap3: pm: use prcm chain handler Tero Kristo
@ 2011-12-09 23:23   ` Kevin Hilman
  2011-12-12  9:55     ` Tero Kristo
  0 siblings, 1 reply; 24+ messages in thread
From: Kevin Hilman @ 2011-12-09 23:23 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, paul, b-cousson

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

> 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.

Also, elaborate that this means this core event code should no longer
clear the IO events since they are now handled by their own handlers.

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

[...]

> @@ -880,12 +848,20 @@ 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, 0, "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, "pm_io", omap3_pm_init);
> +

Why does the "hwmod_io" use IRQF_NO_SUSPEND and this one doesn't?

Kevin

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

* Re: [PATCHv10 06/14] omap3: pm: use prcm chain handler
  2011-12-09 23:23   ` Kevin Hilman
@ 2011-12-12  9:55     ` Tero Kristo
  0 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-12  9:55 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, paul, b-cousson

On Fri, 2011-12-09 at 15:23 -0800, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > 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.
> 
> Also, elaborate that this means this core event code should no longer
> clear the IO events since they are now handled by their own handlers.

Okay.

> 
> > Signed-off-by: Tero Kristo <t-kristo@ti.com>
> 
> [...]
> 
> > @@ -880,12 +848,20 @@ 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, 0, "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, "pm_io", omap3_pm_init);
> > +
> 
> Why does the "hwmod_io" use IRQF_NO_SUSPEND and this one doesn't?

Hmm, good question. Must have been a remain from some old tweak, I'll
take a look at what the flags should actually be.

-Tero



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

* Re: [PATCHv10 00/14] PRCM chain handler
  2011-12-09 22:36 ` [PATCHv10 00/14] PRCM chain handler Kevin Hilman
@ 2011-12-12  9:56   ` Tero Kristo
  0 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-12  9:56 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, paul, b-cousson

On Fri, 2011-12-09 at 14:36 -0800, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > Once more a new version, it was decided that the PRM driver will be
> > dropped for now, and we will have the chain handler support under
> > mach-omap2 directory. This will most likely be addressed in future.
> 
> Just to clarify for others: We decided that since the PRM driver is
> going to take some more time to sort out, we would at least get the
> chained IRQ support in now so we can unblock drivers that need it for
> wakeup support (like UART, USB host, etc.)
> 
> > Other than that, the code is pretty close to what was in version 9,
> > just location has changed from /drivers/mfd to /arch/arm/mach-omap2.
> >
> > Tested with omap3 beagleboard, with dynamic idle and suspend, both
> > retention and off. omap4 should not be an issue seeing the code is
> > close to what was in version 9.
> >
> > TEMP patches can be ignored, they are provided only for testing
> > purposes, and shall be replaced by uart runtime support.
> 
> Can you repost a series without the TEMP patches, and Cc
> linux-arm-kernel as well.
> 
> For testing purposes, you can make a branch available with the temp
> patches included, and mention it in the changelog.

Okay, I'll repost once I have fixed this version hopefully.

-Tero



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

* Re: [PATCHv10 04/14] omap: prm: add support for suspend prepare and finish callbacks
  2011-12-09 23:04   ` Kevin Hilman
@ 2011-12-12  9:57     ` Tero Kristo
  0 siblings, 0 replies; 24+ messages in thread
From: Tero Kristo @ 2011-12-12  9:57 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, paul, b-cousson

On Fri, 2011-12-09 at 15:04 -0800, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > These are needed because runtime PM is disabled during suspend, and
> > it is bad if we get interrupts from the PRCM chain handler during it.
> > This patch masks all the PRCM interrupt events, but does not ack them,
> > if an interrupt is received during suspend. 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.
> 
> You might just update this changelog to clarify why you're using the the
> driver-specific prepare & complete terminology whereas this code is
> using begin/finish hooks as part of platform_pm_ops.
> 
> IOW, state that this will soon be becoming a real driver, so you're
> using the driver terminology.
> 
> Also note that subject uses prepare & finish instead of prepare & complete.

Yea this changelog is outdated, will fix.

-Tero


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

* Re: [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts
  2011-12-09 23:13   ` Kevin Hilman
@ 2011-12-12 10:01     ` Tero Kristo
  2011-12-12 15:07       ` Kevin Hilman
  0 siblings, 1 reply; 24+ messages in thread
From: Tero Kristo @ 2011-12-12 10:01 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, paul, b-cousson

On Fri, 2011-12-09 at 15:13 -0800, Kevin Hilman wrote:
> Tero Kristo <t-kristo@ti.com> writes:
> 
> > OMAP mux now provides a service routine to parse pending wakeup events
> > and to call registered ISR whenever active wakeups are detected. 
> 
> Good.
> 
> > This routine is called directly from PRCM interrupt handler.
> 
> I think this comment is out of date with the code, since you're now
> using a shared IRQ and the interrupt is directly called from the IRQ
> core.
> 
> I'd update the changelog here just commenting on what this IRQ is shared
> with, and how the interrupts are shared.
> 
> Also, a question on optimization.  For every IO wakeup, this will go
> through the list of *all* enabled hwmods.  This could be pretty expensive
> with lots of wakeups.  Maybe we should have another flag for hwmods that
> have wakeups enabled so walking the list of potential wakeup-capable
> hwmods will be as fast as possible.

Optimization of this code is sure possible, and probably even desirable.
In some of the earlier sets I had a separate list for the pad scan, but
it was dropped out due to some comments. It would be possible to add
either a separate list for these within omap_hwmod / mux, or either a
flag which checks for enabled io wakeups.

-Tero



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

* Re: [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts
  2011-12-12 10:01     ` Tero Kristo
@ 2011-12-12 15:07       ` Kevin Hilman
  0 siblings, 0 replies; 24+ messages in thread
From: Kevin Hilman @ 2011-12-12 15:07 UTC (permalink / raw)
  To: t-kristo; +Cc: linux-omap, paul, b-cousson

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

> On Fri, 2011-12-09 at 15:13 -0800, Kevin Hilman wrote:
>> Tero Kristo <t-kristo@ti.com> writes:
>> 
>> > OMAP mux now provides a service routine to parse pending wakeup events
>> > and to call registered ISR whenever active wakeups are detected. 
>> 
>> Good.
>> 
>> > This routine is called directly from PRCM interrupt handler.
>> 
>> I think this comment is out of date with the code, since you're now
>> using a shared IRQ and the interrupt is directly called from the IRQ
>> core.
>> 
>> I'd update the changelog here just commenting on what this IRQ is shared
>> with, and how the interrupts are shared.
>> 
>> Also, a question on optimization.  For every IO wakeup, this will go
>> through the list of *all* enabled hwmods.  This could be pretty expensive
>> with lots of wakeups.  Maybe we should have another flag for hwmods that
>> have wakeups enabled so walking the list of potential wakeup-capable
>> hwmods will be as fast as possible.
>
> Optimization of this code is sure possible, and probably even desirable.
> In some of the earlier sets I had a separate list for the pad scan, but
> it was dropped out due to some comments. It would be possible to add
> either a separate list for these within omap_hwmod / mux, or either a
> flag which checks for enabled io wakeups.

OK, if you prefer, we can optimize in a future patch so we can still
target v3.3 for this series.

Kevin

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

end of thread, other threads:[~2011-12-12 15:07 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-09 14:27 [PATCHv10 00/14] PRCM chain handler Tero Kristo
2011-12-09 14:27 ` [PATCHv10 01/14] OMAP2+: hwmod: Add API to enable IO ring wakeup Tero Kristo
2011-12-09 14:27 ` [PATCHv10 02/14] OMAP2+: hwmod: Add API to check IO PAD wakeup status Tero Kristo
2011-12-09 14:27 ` [PATCHv10 03/14] omap: prm: add support for chain interrupt handler Tero Kristo
2011-12-09 14:27 ` [PATCHv10 04/14] omap: prm: add support for suspend prepare and finish callbacks Tero Kristo
2011-12-09 23:04   ` Kevin Hilman
2011-12-12  9:57     ` Tero Kristo
2011-12-09 14:27 ` [PATCHv10 05/14] OMAP2+: mux: add support for PAD wakeup interrupts Tero Kristo
2011-12-09 23:13   ` Kevin Hilman
2011-12-12 10:01     ` Tero Kristo
2011-12-12 15:07       ` Kevin Hilman
2011-12-09 14:27 ` [PATCHv10 06/14] omap3: pm: use prcm chain handler Tero Kristo
2011-12-09 23:23   ` Kevin Hilman
2011-12-12  9:55     ` Tero Kristo
2011-12-09 14:27 ` [PATCHv10 07/14] OMAP3: pm: do not enable PRCM MPU interrupts manually Tero Kristo
2011-12-09 14:27 ` [PATCHv10 08/14] TEMP: serial: added mux support Tero Kristo
2011-12-09 14:27 ` [PATCHv10 09/14] TEMP: 4430sdp: use common serial init with " Tero Kristo
2011-12-09 14:27 ` [PATCHv10 10/14] TEMP: mux: added trace for io wkup event Tero Kristo
2011-12-09 14:27 ` [PATCHv10 11/14] TEMP: OMAP3: pm: remove serial resume / idle calls from idle path Tero Kristo
2011-12-09 14:27 ` [PATCHv10 12/14] TEMP: OMAP3: serial: made serial to work properly with PRCM chain handler Tero Kristo
2011-12-09 14:27 ` [PATCHv10 13/14] TEMP: OMAP: serial: remove padconf hacks Tero Kristo
2011-12-09 14:27 ` [PATCHv10 14/14] TEMP: OMAP device: change pr_warnings to pr_debugs Tero Kristo
2011-12-09 22:36 ` [PATCHv10 00/14] PRCM chain handler Kevin Hilman
2011-12-12  9:56   ` Tero Kristo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).