Explorar el Código

Merge branch 'pm-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-fixes-for-linus

Tony Lindgren hace 15 años
padre
commit
ccaae273c3

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

@@ -137,7 +137,7 @@ return_sleep_time:
 	local_irq_enable();
 	local_irq_enable();
 	local_fiq_enable();
 	local_fiq_enable();
 
 
-	return (u32)timespec_to_ns(&ts_idle)/1000;
+	return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC;
 }
 }
 
 
 /**
 /**

+ 18 - 0
arch/arm/mach-omap2/irq.c

@@ -274,4 +274,22 @@ void omap_intc_restore_context(void)
 	}
 	}
 	/* MIRs are saved and restore with other PRCM registers */
 	/* MIRs are saved and restore with other PRCM registers */
 }
 }
+
+void omap3_intc_suspend(void)
+{
+	/* A pending interrupt would prevent OMAP from entering suspend */
+	omap_ack_irq(0);
+}
+
+void omap3_intc_prepare_idle(void)
+{
+	/* Disable autoidle as it can stall interrupt controller */
+	intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG);
+}
+
+void omap3_intc_resume_idle(void)
+{
+	/* Re-enable autoidle */
+	intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG);
+}
 #endif /* CONFIG_ARCH_OMAP3 */
 #endif /* CONFIG_ARCH_OMAP3 */

+ 6 - 6
arch/arm/mach-omap2/pm-debug.c

@@ -54,8 +54,6 @@ int omap2_pm_debug;
 	regs[reg_count++].val = \
 	regs[reg_count++].val = \
 			 __raw_readl(OMAP2_L4_IO_ADDRESS(0x480fe000 + (off)))
 			 __raw_readl(OMAP2_L4_IO_ADDRESS(0x480fe000 + (off)))
 
 
-static int __init pm_dbg_init(void);
-
 void omap2_pm_dump(int mode, int resume, unsigned int us)
 void omap2_pm_dump(int mode, int resume, unsigned int us)
 {
 {
 	struct reg {
 	struct reg {
@@ -167,6 +165,8 @@ struct dentry *pm_dbg_dir;
 
 
 static int pm_dbg_init_done;
 static int pm_dbg_init_done;
 
 
+static int __init pm_dbg_init(void);
+
 enum {
 enum {
 	DEBUG_FILE_COUNTERS = 0,
 	DEBUG_FILE_COUNTERS = 0,
 	DEBUG_FILE_TIMERS,
 	DEBUG_FILE_TIMERS,
@@ -488,9 +488,11 @@ int pm_dbg_regset_init(int reg_set)
 
 
 static int pwrdm_suspend_get(void *data, u64 *val)
 static int pwrdm_suspend_get(void *data, u64 *val)
 {
 {
-	*val = omap3_pm_get_suspend_state((struct powerdomain *)data);
+	int ret;
+	ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
+	*val = ret;
 
 
-	if (*val >= 0)
+	if (ret >= 0)
 		return 0;
 		return 0;
 	return *val;
 	return *val;
 }
 }
@@ -604,6 +606,4 @@ static int __init pm_dbg_init(void)
 }
 }
 arch_initcall(pm_dbg_init);
 arch_initcall(pm_dbg_init);
 
 
-#else
-void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) {}
 #endif
 #endif

+ 6 - 2
arch/arm/mach-omap2/pm.h

@@ -32,12 +32,16 @@ extern struct omap_dm_timer *gptimer_wakeup;
 #ifdef CONFIG_PM_DEBUG
 #ifdef CONFIG_PM_DEBUG
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
 extern int omap2_pm_debug;
 extern int omap2_pm_debug;
+#else
+#define omap2_pm_dump(mode, resume, us)		do {} while (0);
+#define omap2_pm_debug				0
+#endif
+
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
 extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
 extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
 extern int pm_dbg_regset_save(int reg_set);
 extern int pm_dbg_regset_save(int reg_set);
 extern int pm_dbg_regset_init(int reg_set);
 extern int pm_dbg_regset_init(int reg_set);
 #else
 #else
-#define omap2_pm_dump(mode, resume, us)		do {} while (0);
-#define omap2_pm_debug				0
 #define pm_dbg_update_time(pwrdm, prev) do {} while (0);
 #define pm_dbg_update_time(pwrdm, prev) do {} while (0);
 #define pm_dbg_regset_save(reg_set) do {} while (0);
 #define pm_dbg_regset_save(reg_set) do {} while (0);
 #define pm_dbg_regset_init(reg_set) do {} while (0);
 #define pm_dbg_regset_init(reg_set) do {} while (0);

+ 26 - 21
arch/arm/mach-omap2/pm34xx.c

@@ -26,6 +26,7 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
 
 
 #include <plat/sram.h>
 #include <plat/sram.h>
 #include <plat/clockdomain.h>
 #include <plat/clockdomain.h>
@@ -126,7 +127,15 @@ static void omap3_core_save_context(void)
 	/* wait for the save to complete */
 	/* wait for the save to complete */
 	while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
 	while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
 			& PADCONF_SAVE_DONE))
 			& PADCONF_SAVE_DONE))
-		;
+		udelay(1);
+
+	/*
+	 * Force write last pad into memory, as this can fail in some
+	 * cases according to erratas 1.157, 1.185
+	 */
+	omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14),
+		OMAP343X_CONTROL_MEM_WKUP + 0x2a0);
+
 	/* Save the Interrupt controller context */
 	/* Save the Interrupt controller context */
 	omap_intc_save_context();
 	omap_intc_save_context();
 	/* Save the GPMC context */
 	/* Save the GPMC context */
@@ -392,6 +401,7 @@ void omap_sram_idle(void)
 		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
 		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
 		omap3_enable_io_chain();
 		omap3_enable_io_chain();
 	}
 	}
+	omap3_intc_prepare_idle();
 
 
 	/*
 	/*
 	* On EMU/HS devices ROM code restores a SRDC value
 	* On EMU/HS devices ROM code restores a SRDC value
@@ -438,6 +448,7 @@ void omap_sram_idle(void)
 					       OMAP3430_GR_MOD,
 					       OMAP3430_GR_MOD,
 					       OMAP3_PRM_VOLTCTRL_OFFSET);
 					       OMAP3_PRM_VOLTCTRL_OFFSET);
 	}
 	}
+	omap3_intc_resume_idle();
 
 
 	/* PER */
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
 	if (per_next_state < PWRDM_POWER_ON) {
@@ -578,6 +589,8 @@ static int omap3_pm_suspend(void)
 	}
 	}
 
 
 	omap_uart_prepare_suspend();
 	omap_uart_prepare_suspend();
+	omap3_intc_suspend();
+
 	omap_sram_idle();
 	omap_sram_idle();
 
 
 restore:
 restore:
@@ -835,6 +848,8 @@ static void __init prcm_setup_regs(void)
 			CM_AUTOIDLE);
 			CM_AUTOIDLE);
 	}
 	}
 
 
+	omap_ctrl_writel(OMAP3430_AUTOIDLE, OMAP2_CONTROL_SYSCONFIG);
+
 	/*
 	/*
 	 * Set all plls to autoidle. This is needed until autoidle is
 	 * Set all plls to autoidle. This is needed until autoidle is
 	 * enabled by clockfw
 	 * enabled by clockfw
@@ -875,15 +890,23 @@ static void __init prcm_setup_regs(void)
 	prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
 	prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
 			  OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 			  OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 
 
+	/* Enable PM_WKEN to support DSS LPR */
+	prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS,
+				OMAP3430_DSS_MOD, PM_WKEN);
+
 	/* Enable wakeups in PER */
 	/* Enable wakeups in PER */
 	prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
 	prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
 			  OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
 			  OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
-			  OMAP3430_EN_GPIO6 | OMAP3430_EN_UART3,
+			  OMAP3430_EN_GPIO6 | OMAP3430_EN_UART3 |
+			  OMAP3430_EN_MCBSP2 | OMAP3430_EN_MCBSP3 |
+			  OMAP3430_EN_MCBSP4,
 			  OMAP3430_PER_MOD, PM_WKEN);
 			  OMAP3430_PER_MOD, PM_WKEN);
 	/* and allow them to wake up MPU */
 	/* and allow them to wake up MPU */
 	prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
 	prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
 			  OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
 			  OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
-			  OMAP3430_GRPSEL_GPIO6 | OMAP3430_EN_UART3,
+			  OMAP3430_GRPSEL_GPIO6 | OMAP3430_EN_UART3 |
+			  OMAP3430_EN_MCBSP2 | OMAP3430_EN_MCBSP3 |
+			  OMAP3430_EN_MCBSP4,
 			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
 			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
 
 
 	/* Don't attach IVA interrupts */
 	/* Don't attach IVA interrupts */
@@ -904,24 +927,6 @@ static void __init prcm_setup_regs(void)
 	/* Clear any pending PRCM interrupts */
 	/* Clear any pending PRCM interrupts */
 	prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 	prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
 
-	/* Don't attach IVA interrupts */
-	prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
-	prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
-	prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
-	prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
-
-	/* Clear any pending 'reset' flags */
-	prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST);
-
-	/* Clear any pending PRCM interrupts */
-	prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-
 	omap3_iva_idle();
 	omap3_iva_idle();
 	omap3_d2d_idle();
 	omap3_d2d_idle();
 }
 }

+ 0 - 11
arch/arm/mach-omap2/prcm.c

@@ -44,7 +44,6 @@ struct omap3_prcm_regs {
 	u32 iva2_cm_clksel2;
 	u32 iva2_cm_clksel2;
 	u32 cm_sysconfig;
 	u32 cm_sysconfig;
 	u32 sgx_cm_clksel;
 	u32 sgx_cm_clksel;
-	u32 wkup_cm_clksel;
 	u32 dss_cm_clksel;
 	u32 dss_cm_clksel;
 	u32 cam_cm_clksel;
 	u32 cam_cm_clksel;
 	u32 per_cm_clksel;
 	u32 per_cm_clksel;
@@ -53,7 +52,6 @@ struct omap3_prcm_regs {
 	u32 pll_cm_autoidle2;
 	u32 pll_cm_autoidle2;
 	u32 pll_cm_clksel4;
 	u32 pll_cm_clksel4;
 	u32 pll_cm_clksel5;
 	u32 pll_cm_clksel5;
-	u32 pll_cm_clken;
 	u32 pll_cm_clken2;
 	u32 pll_cm_clken2;
 	u32 cm_polctrl;
 	u32 cm_polctrl;
 	u32 iva2_cm_fclken;
 	u32 iva2_cm_fclken;
@@ -77,7 +75,6 @@ struct omap3_prcm_regs {
 	u32 usbhost_cm_iclken;
 	u32 usbhost_cm_iclken;
 	u32 iva2_cm_autiidle2;
 	u32 iva2_cm_autiidle2;
 	u32 mpu_cm_autoidle2;
 	u32 mpu_cm_autoidle2;
-	u32 pll_cm_autoidle;
 	u32 iva2_cm_clkstctrl;
 	u32 iva2_cm_clkstctrl;
 	u32 mpu_cm_clkstctrl;
 	u32 mpu_cm_clkstctrl;
 	u32 core_cm_clkstctrl;
 	u32 core_cm_clkstctrl;
@@ -274,7 +271,6 @@ void omap3_prcm_save_context(void)
 	prcm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
 	prcm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
 	prcm_context.sgx_cm_clksel =
 	prcm_context.sgx_cm_clksel =
 			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
 			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
-	prcm_context.wkup_cm_clksel = cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
 	prcm_context.dss_cm_clksel =
 	prcm_context.dss_cm_clksel =
 			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
 			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
 	prcm_context.cam_cm_clksel =
 	prcm_context.cam_cm_clksel =
@@ -291,8 +287,6 @@ void omap3_prcm_save_context(void)
 			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
 			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
 	prcm_context.pll_cm_clksel5 =
 	prcm_context.pll_cm_clksel5 =
 			 cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
 			 cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
-	prcm_context.pll_cm_clken =
-			cm_read_mod_reg(PLL_MOD, CM_CLKEN);
 	prcm_context.pll_cm_clken2 =
 	prcm_context.pll_cm_clken2 =
 			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
 			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
 	prcm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
 	prcm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
@@ -338,8 +332,6 @@ void omap3_prcm_save_context(void)
 			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
 			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
 	prcm_context.mpu_cm_autoidle2 =
 	prcm_context.mpu_cm_autoidle2 =
 			 cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
 			 cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
-	prcm_context.pll_cm_autoidle =
-			 cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
 	prcm_context.iva2_cm_clkstctrl =
 	prcm_context.iva2_cm_clkstctrl =
 			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL);
 			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL);
 	prcm_context.mpu_cm_clkstctrl =
 	prcm_context.mpu_cm_clkstctrl =
@@ -431,7 +423,6 @@ void omap3_prcm_restore_context(void)
 	__raw_writel(prcm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
 	__raw_writel(prcm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
 	cm_write_mod_reg(prcm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
 	cm_write_mod_reg(prcm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
 					 CM_CLKSEL);
 					 CM_CLKSEL);
-	cm_write_mod_reg(prcm_context.wkup_cm_clksel, WKUP_MOD, CM_CLKSEL);
 	cm_write_mod_reg(prcm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
 	cm_write_mod_reg(prcm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
 					 CM_CLKSEL);
 					 CM_CLKSEL);
 	cm_write_mod_reg(prcm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
 	cm_write_mod_reg(prcm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
@@ -448,7 +439,6 @@ void omap3_prcm_restore_context(void)
 					OMAP3430ES2_CM_CLKSEL4);
 					OMAP3430ES2_CM_CLKSEL4);
 	cm_write_mod_reg(prcm_context.pll_cm_clksel5, PLL_MOD,
 	cm_write_mod_reg(prcm_context.pll_cm_clksel5, PLL_MOD,
 					 OMAP3430ES2_CM_CLKSEL5);
 					 OMAP3430ES2_CM_CLKSEL5);
-	cm_write_mod_reg(prcm_context.pll_cm_clken, PLL_MOD, CM_CLKEN);
 	cm_write_mod_reg(prcm_context.pll_cm_clken2, PLL_MOD,
 	cm_write_mod_reg(prcm_context.pll_cm_clken2, PLL_MOD,
 					OMAP3430ES2_CM_CLKEN2);
 					OMAP3430ES2_CM_CLKEN2);
 	__raw_writel(prcm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
 	__raw_writel(prcm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
@@ -487,7 +477,6 @@ void omap3_prcm_restore_context(void)
 	cm_write_mod_reg(prcm_context.iva2_cm_autiidle2, OMAP3430_IVA2_MOD,
 	cm_write_mod_reg(prcm_context.iva2_cm_autiidle2, OMAP3430_IVA2_MOD,
 					CM_AUTOIDLE2);
 					CM_AUTOIDLE2);
 	cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
 	cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
-	cm_write_mod_reg(prcm_context.pll_cm_autoidle, PLL_MOD, CM_AUTOIDLE);
 	cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
 	cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
 					CM_CLKSTCTRL);
 					CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD, CM_CLKSTCTRL);
 	cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD, CM_CLKSTCTRL);

+ 9 - 4
arch/arm/mach-omap2/sleep34xx.S

@@ -245,7 +245,8 @@ restore:
 	mov	r1, #0		@ set task id for ROM code in r1
 	mov	r1, #0		@ set task id for ROM code in r1
 	mov	r2, #4		@ set some flags in r2, r6
 	mov	r2, #4		@ set some flags in r2, r6
 	mov	r6, #0xff
 	mov	r6, #0xff
-	adr	r3, write_aux_control_params	@ r3 points to parameters
+	ldr	r4, scratchpad_base
+	ldr	r3, [r4, #0xBC]	@ r3 points to parameters
 	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
 	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
 	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
 	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
 	.word	0xE1600071		@ call SMI monitor (smi #1)
 	.word	0xE1600071		@ call SMI monitor (smi #1)
@@ -253,14 +254,14 @@ restore:
 	b	logic_l1_restore
 	b	logic_l1_restore
 l2_inv_api_params:
 l2_inv_api_params:
 	.word   0x1, 0x00
 	.word   0x1, 0x00
-write_aux_control_params:
-	.word   0x1, 0x72
 l2_inv_gp:
 l2_inv_gp:
 	/* Execute smi to invalidate L2 cache */
 	/* Execute smi to invalidate L2 cache */
 	mov r12, #0x1                         @ set up to invalide L2
 	mov r12, #0x1                         @ set up to invalide L2
 smi:    .word 0xE1600070		@ Call SMI monitor (smieq)
 smi:    .word 0xE1600070		@ Call SMI monitor (smieq)
 	/* Write to Aux control register to set some bits */
 	/* Write to Aux control register to set some bits */
-	mov	r0, #0x72
+	ldr	r4, scratchpad_base
+	ldr	r3, [r4,#0xBC]
+	ldr	r0, [r3,#4]
 	mov	r12, #0x3
 	mov	r12, #0x3
 	.word 0xE1600070	@ Call SMI monitor (smieq)
 	.word 0xE1600070	@ Call SMI monitor (smieq)
 logic_l1_restore:
 logic_l1_restore:
@@ -271,6 +272,7 @@ logic_l1_restore:
 
 
 	ldr	r4, scratchpad_base
 	ldr	r4, scratchpad_base
 	ldr	r3, [r4,#0xBC]
 	ldr	r3, [r4,#0xBC]
+	adds	r3, r3, #8
 	ldmia	r3!, {r4-r6}
 	ldmia	r3!, {r4-r6}
 	mov	sp, r4
 	mov	sp, r4
 	msr	spsr_cxsf, r5
 	msr	spsr_cxsf, r5
@@ -387,6 +389,9 @@ usettbr0:
 save_context_wfi:
 save_context_wfi:
 	/*b	save_context_wfi*/	@ enable to debug save code
 	/*b	save_context_wfi*/	@ enable to debug save code
 	mov	r8, r0 /* Store SDRAM address in r8 */
 	mov	r8, r0 /* Store SDRAM address in r8 */
+	mrc	p15, 0, r5, c1, c0, 1	@ Read Auxiliary Control Register
+	mov	r4, #0x1		@ Number of parameters for restore call
+	stmia	r8!, {r4-r5}
         /* Check what that target sleep state is:stored in r1*/
         /* Check what that target sleep state is:stored in r1*/
         /* 1 - Only L1 and logic lost */
         /* 1 - Only L1 and logic lost */
         /* 2 - Only L2 lost */
         /* 2 - Only L2 lost */

+ 26 - 0
arch/arm/plat-omap/common.c

@@ -172,6 +172,32 @@ unsigned long long sched_clock(void)
 				  clocksource_32k.mult, clocksource_32k.shift);
 				  clocksource_32k.mult, clocksource_32k.shift);
 }
 }
 
 
+/**
+ * read_persistent_clock -  Return time from a persistent clock.
+ *
+ * Reads the time from a source which isn't disabled during PM, the
+ * 32k sync timer.  Convert the cycles elapsed since last read into
+ * nsecs and adds to a monotonically increasing timespec.
+ */
+static struct timespec persistent_ts;
+static cycles_t cycles, last_cycles;
+void read_persistent_clock(struct timespec *ts)
+{
+	unsigned long long nsecs;
+	cycles_t delta;
+	struct timespec *tsp = &persistent_ts;
+
+	last_cycles = cycles;
+	cycles = clocksource_32k.read(&clocksource_32k);
+	delta = cycles - last_cycles;
+
+	nsecs = clocksource_cyc2ns(delta,
+				   clocksource_32k.mult, clocksource_32k.shift);
+
+	timespec_add_ns(tsp, nsecs);
+	*ts = *tsp;
+}
+
 static int __init omap_init_clocksource_32k(void)
 static int __init omap_init_clocksource_32k(void)
 {
 {
 	static char err[] __initdata = KERN_ERR
 	static char err[] __initdata = KERN_ERR

+ 3 - 0
arch/arm/plat-omap/include/plat/irqs.h

@@ -499,6 +499,9 @@ extern void omap_init_irq(void);
 extern int omap_irq_pending(void);
 extern int omap_irq_pending(void);
 void omap_intc_save_context(void);
 void omap_intc_save_context(void);
 void omap_intc_restore_context(void);
 void omap_intc_restore_context(void);
+void omap3_intc_suspend(void);
+void omap3_intc_prepare_idle(void);
+void omap3_intc_resume_idle(void);
 #endif
 #endif
 
 
 #include <mach/hardware.h>
 #include <mach/hardware.h>