diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
| -rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 51 | 
1 files changed, 47 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 841d4c5ed8b..488d595d8e4 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -39,7 +39,9 @@  struct power_state {  	struct powerdomain *pwrdm;  	u32 next_state; +#ifdef CONFIG_SUSPEND  	u32 saved_state; +#endif  	struct list_head node;  }; @@ -293,6 +295,9 @@ out:  	local_irq_enable();  } +#ifdef CONFIG_SUSPEND +static suspend_state_t suspend_state; +  static int omap3_pm_prepare(void)  {  	disable_hlt(); @@ -321,7 +326,6 @@ static int omap3_pm_suspend(void)  restore:  	/* Restore next_pwrsts */  	list_for_each_entry(pwrst, &pwrst_list, node) { -		set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);  		state = pwrdm_read_prev_pwrst(pwrst->pwrdm);  		if (state > pwrst->next_state) {  			printk(KERN_INFO "Powerdomain (%s) didn't enter " @@ -329,6 +333,7 @@ restore:  			       pwrst->pwrdm->name, pwrst->next_state);  			ret = -1;  		} +		set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);  	}  	if (ret)  		printk(KERN_ERR "Could not enter target state in pm_suspend\n"); @@ -339,11 +344,11 @@ restore:  	return ret;  } -static int omap3_pm_enter(suspend_state_t state) +static int omap3_pm_enter(suspend_state_t unused)  {  	int ret = 0; -	switch (state) { +	switch (suspend_state) {  	case PM_SUSPEND_STANDBY:  	case PM_SUSPEND_MEM:  		ret = omap3_pm_suspend(); @@ -360,12 +365,30 @@ static void omap3_pm_finish(void)  	enable_hlt();  } +/* Hooks to enable / disable UART interrupts during suspend */ +static int omap3_pm_begin(suspend_state_t state) +{ +	suspend_state = state; +	omap_uart_enable_irqs(0); +	return 0; +} + +static void omap3_pm_end(void) +{ +	suspend_state = PM_SUSPEND_ON; +	omap_uart_enable_irqs(1); +	return; +} +  static struct platform_suspend_ops omap_pm_ops = { +	.begin		= omap3_pm_begin, +	.end		= omap3_pm_end,  	.prepare	= omap3_pm_prepare,  	.enter		= omap3_pm_enter,  	.finish		= omap3_pm_finish,  	.valid		= suspend_valid_only_mem,  }; +#endif /* CONFIG_SUSPEND */  /** @@ -613,6 +636,24 @@ static void __init prcm_setup_regs(void)  	/* Clear any pending PRCM interrupts */  	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_d2d_idle();  } @@ -652,7 +693,7 @@ static int __init clkdms_setup(struct clockdomain *clkdm)  	return 0;  } -int __init omap3_pm_init(void) +static int __init omap3_pm_init(void)  {  	struct power_state *pwrst, *tmp;  	int ret; @@ -692,7 +733,9 @@ int __init omap3_pm_init(void)  	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,  					 omap34xx_cpu_suspend_sz); +#ifdef CONFIG_SUSPEND  	suspend_set_ops(&omap_pm_ops); +#endif /* CONFIG_SUSPEND */  	pm_idle = omap3_pm_idle;  |