aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h1
-rw-r--r--arch/arm/mach-omap2/omap4-mpuss-lowpower.c7
-rw-r--r--arch/arm/mach-omap2/pm44xx.c33
3 files changed, 41 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index c9a56a2..6360651 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -61,6 +61,7 @@ extern void gic_cpu_enable(void);
extern void gic_cpu_disable(void);
extern void gic_dist_enable(void);
extern void gic_dist_disable(void);
+extern u32 gic_cpu_read(u32 reg);
extern void omap_smc1(u32 fn, u32 arg);
extern void omap_bus_sync(void);
diff --git a/arch/arm/mach-omap2/omap4-mpuss-lowpower.c b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
index 3bce7e6..ce55010 100644
--- a/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
@@ -97,6 +97,7 @@ struct omap4_cpu_pm_info {
};
static void __iomem *gic_dist_base;
+static void __iomem *gic_cpu_base;
static void __iomem *sar_base;
static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
@@ -112,6 +113,11 @@ static inline u32 gic_readl(u32 offset, u8 idx)
return __raw_readl(gic_dist_base + offset + 4 * idx);
}
+u32 gic_cpu_read(u32 reg)
+{
+ return __raw_readl(gic_cpu_base + reg);
+}
+
/*
* Set the CPUx powerdomain's previous power state
*/
@@ -507,6 +513,7 @@ int __init omap4_mpuss_init(void)
/* Get GIC and SAR RAM base addresses */
sar_base = omap4_get_sar_ram_base();
gic_dist_base = omap4_get_gic_dist_base();
+ gic_cpu_base = omap4_get_gic_cpu_base();
if (omap_rev() == OMAP4430_REV_ES1_0) {
WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 3eea05f..104ca5e 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -20,7 +20,9 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/irq.h>
+#include <asm/hardware/gic.h>
#include <mach/omap4-common.h>
#include <plat/common.h>
@@ -43,6 +45,8 @@
#include "voltage.h"
#include "vc.h"
+#define OMAP44XX_IRQ_GIC_START 32
+
struct power_state {
struct powerdomain *pwrdm;
u32 next_state;
@@ -164,6 +168,34 @@ static void omap4_pm_set_wakeups(int enable)
irq_set_irq_wake(OMAP44XX_IRQ_SYS_1N, enable);
}
+#ifdef CONFIG_PM_DEBUG
+static void omap4_print_wakeirq(void)
+{
+ int irq;
+ struct irq_desc *desc;
+
+ irq = gic_cpu_read(GIC_CPU_HIGHPRI) & 0x3ff;
+
+ if ((irq == 1022) || (irq == 1023)) {
+ pr_info("GIC returns spurious interrupt for resume IRQ\n");
+ return;
+ }
+
+ irq -= OMAP44XX_IRQ_GIC_START;
+ desc = irq_to_desc(irq);
+
+ if (!desc || !desc->action || !desc->action->name)
+ pr_info("Resume caused by IRQ %d\n", irq);
+ else
+ pr_info("Resume caused by IRQ %d, %s\n", irq,
+ desc->action->name);
+}
+#else
+static void omap4_print_wakeirq(void)
+{
+}
+#endif
+
static int omap4_pm_suspend(void)
{
struct power_state *pwrst;
@@ -209,6 +241,7 @@ static int omap4_pm_suspend(void)
* More details can be found in OMAP4430 TRM section 4.3.4.2.
*/
omap4_enter_sleep(0, PWRDM_POWER_OFF);
+ omap4_print_wakeirq();
/* Disable wake-up irq's */
omap4_pm_set_wakeups(0);